从Windows窗体,LineShape和ShapeContainer数组中删除LineShape

时间:2013-01-02 14:43:14

标签: vb.net visual-studio-2010 line

我使用下面的代码将多个LineShape控件添加到Windows窗体。请注意全局声明的mLineShapes()mShapeContainter()数组(在代码底部),它们在创建后存储每个新的LineShape对象。

目前,我没有成功从表单中删除给定的LineShape控件(即使我知道它的数组索引),也无法删除数组元素而不会为删除的元素导致Nothing。显然,一旦我从这些数组中删除元素,它就要求将具有较大索引的所有剩余元素复制到较低的值以填充Nothing无效元素。鉴于这些情况,可以使用列表而不是mLineShapes()mShapeContainer()数组吗?

        enter code here' create new ShapeContainer
        Dim sSCTemp As New ShapeContainer

        ' add ShapeContainer to Form
        sSCTemp.Parent = Me

        ' create new LineShape
        Dim sLSTemp As New LineShape
        sLSTemp.BorderColor = Color.Black
        sLSTemp.BorderWidth = 2
        sLSTemp.Cursor = Cursors.Cross
        ' add LineShape to ShapeContainer
        sLSTemp.Parent = sSCTemp

        ' set starting and ending coordinates for the line
        sLSTemp.StartPoint = New System.Drawing.Point(siSCCount * 20, 60 + siSCCount * 60)
        sLSTemp.EndPoint = New System.Drawing.Point(100 + siSCCount * 20, 110 + siSCCount * 60)

        ' set new LineShape to top of z-order
        sLSTemp.BringToFront()
        sSCTemp.BringToFront()

        ' connect ContextMenuStrip to LineShape
        sLSTemp.ContextMenuStrip = mLsCtm1

        ' add new LineShape to arrays
        ReDim Preserve mLineShapes(siSCCount)
        ReDim Preserve mShapeContainer(siSCCount)

        mLineShapes(siSCCount) = sLSTemp
        mLineShapes(siSCCount).Name = "LineShape" & siSCCount
        mShapeContainer(siSCCount) = sSCTemp
        mShapeContainer(siSCCount).Name = "ShapeContainer" & siSCCount

除上述之外,每个端点 从数组中选择LineShape以便可以移动它们。一个例子如下:

        Dim siSCId As Integer
        Dim myShapeContainer As ShapeContainer
        myShapeContainer = CType(sender, ShapeContainer)
        Dim myLineShape As LineShape
        ' get index of the actual ShapeContainer in ShapeContainer array
        siSCId = Array.IndexOf(mShapeContainer, sender)

        If siSCId > -1 Then
            myLineShape = mLineShapes(siSCId)
            If MouseIsNearBy(myLineShape.EndPoint) Then
                myLineShape.BorderColor = Color.Red
                NearLineEndPoint = True
            End If
            If MouseIsNearBy(myLineShape.EndPoint) = False Then
                myLineShape.BorderColor = Color.Black
                NearLineEndPoint = False
            End If
            If (dragStartPoint) Then
                myLineShape.StartPoint = New Point(oldStartPoint.X + e.X - oldMouseX, oldStartPoint.Y + e.Y - oldMouseY)
            End If
        End If 

因此,如果我只是在不使用mLineShapes()和mShapeControl()数组的情况下将新的LineShape添加到表单控件中,如何修改上面的代码(在存储阵列中找到LineShape)以便该行可以被修改?我想如果我点击一个LineShape,我可以使用.sourcecontrol或.parent得到它的名字?

更新5/9/2019

右键单击Form1上的控件并从ContextMenuStrip中选择“链接”命令后,将触发以下方法(ctmsconnect)以绘制一个新的LineShape控件,然后用户将其拖放到下一个控件中。流程。问题是,是不是需要LineShapes(“Lines”)的列表?

(在Form1类声明中):

  Dim SC As New ShapeContainer
  Dim Lines As New List(Of LineShape)

  Private Sub ctmsconnect_Click(sender As System.Object, e As System.EventArgs) Handles ctmsconnect.Click
        mLineWidth = 1
        Dim myItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
        Dim cms As ContextMenuStrip = CType(myItem.Owner, ContextMenuStrip)
        Dim x As Integer = cms.SourceControl.Right - 2
        Dim y As Integer = cms.SourceControl.Top + (cms.SourceControl.Height / 2 - 12)
        Dim LS As New LineShape
        NumLineShapes += 1
        LS.Name = "LineShape" & NumLineShapes
        LS.BorderColor = Color.Black
        LS.BorderWidth = 2

        'Set starting and ending coordinates for the line
        LS.StartPoint = New Point(x, y)
        LS.EndPoint = New Point(x + 80, y - 5)

        'Set new LineShape to top of z-order
        LS.BringToFront()

        Dim nxgContextMenuStrip As New ContextMenuStrip
        LS.ContextMenuStrip = nxgContextMenuStrip
        LS.Tag = "LineShape" & NumLineShapes & "_Delete"

        'Attach an event handler for the ContextMenuStrip control's Opening event. 
        AddHandler nxgContextMenuStrip.Opening, AddressOf cms_Opening
        numconnectedlineendpoints += 1
        Dim myValues As New List(Of String)
        myValues.Add(cms.SourceControl.Name)
        DropLineOriginalObjectName = cms.SourceControl.Name
        OrigDropControl = cms.SourceControl
        myValues.Add(LS.Name)
        myValues.Add("linestart")
        dicGUIControls.Add(numconnectedlineendpoints, myValues)
        Lines.Add(LS)
        SC.Shapes.Add(LS)
        Me.Refresh()

    End Sub

2 个答案:

答案 0 :(得分:3)

您不需要数组,只需使用控件集合。您应该将它们添加到集合中,而不是设置控件的父级:

'sSCTemp.Parent = Me
Me.Controls.Add(sSCTemp)

要删除它们,可以通过name属性引用它们:

If Me.Controls.ContainsKey("ShapeContainer1") Then
  Me.Controls.RemoveByKey("ShapeContainer1")
End If

必须通过Shape集合访问ShapeContainer中的形状控件:

If Me.Controls.ContainsKey("ShapeContainer1") Then
  Dim sc As ShapeContainer = DirectCast(Me.Controls("ShapeContainer1"), ShapeContainer)
  If sc.Shapes.ContainsKey("LineShape2") Then
    sc.Shapes.RemoveAt(sc.Shapes.IndexOfKey("LineShape2"))
  End If
End If

读取StartPoint和EndPoint属性的示例:

Dim sb As New StringBuilder
For Each ls As LineShape In Me.ShapeContainer1.Shapes
  sb.AppendLine(ls.StartPoint.ToString & " - " & ls.EndPoint.ToString)
Next
MessageBox.Show(sb.ToString)

注意:ShapeContainer Class特别说明:

  

请注意,不要为每个表单或容器创建多个ShapeContainer;这样做可能会引入意外行为。如果在编写代码以编程方式创建一个表单或容器之后向表单或容器添加设计时行或形状控件,则应修改该代码以使用设计器创建的ShapeContainer。

答案 1 :(得分:0)

Public Class Form1

    Dim canvas As New Microsoft.VisualBasic.PowerPacks.ShapeContainer
    ' Set the form as the parent of the ShapeContainer.

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        canvas.Parent = Me
        ' Set the ShapeContainer as the parent of the LineShape.
    End Sub

    Private Sub Form1_MouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
        If RadioButton1.Checked = True Then
            Dim line1 As New Microsoft.VisualBasic.PowerPacks.LineShape
            line1.Parent = canvas
            ' Set the starting and ending coordinates for the line.
            line1.StartPoint = New System.Drawing.Point(Me.Width / 2, 0)
            line1.EndPoint = New System.Drawing.Point(e.X, e.Y)
            TextBox1.Text = canvas.Shapes.Count.ToString
            line1.Name = "MyShape"
            canvas.Shapes.Add(line1)
            AddHandler line1.Click, AddressOf LineClick
        End If
    End Sub

    Private Sub LineClick(sender As Object, e As EventArgs)
        ' Here is where we take the object that is sender from the arguments and cast it to its specific control
        If RadioButton2.Checked = True Then
            ' I could just as easily use
            CType(sender, PowerPacks.LineShape).Dispose()
            TextBox1.Text = canvas.Shapes.Count
        End If
    End Sub

End Class