Удалить LineShape из массивов Windows Form, LineShape и ShapeContainer
Я использую приведенный ниже код для добавления нескольких элементов управления LineShape в форму Windows. Обратите внимание на глобально объявленные массивы mLineShapes()
и mShapeContainter()
(в нижней части кода), которые хранят каждый новый объект LineShape после его создания.
В настоящее время мне не удалось удалить данный элемент управления LineShape из формы (даже если я знаю его индекс массива), а также не удается удалить элемент массива, не вызвав ничего для удаленного элемента. Очевидно, как только я удалю элемент из этих массивы, он требует, чтобы все остальные элементы с большими индексами копировались в меньшие значения, чтобы заполнить ничем не опустошенный элемент. Учитывая эти обстоятельства, можно ли использовать списки вместо массивов 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
В дополнение к вышесказанному, конечные точки каждого Линейные формы выбираются из массивов таким образом, чтобы их можно было перемещать. Пример приведен ниже:
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 () ans массивы mShapeControl (), как я могу изменить приведенный выше код (который находит форму строки в массивах хранения), чтобы можно было изменить строку? Я думаю, что если я нажму на Линешейп ,я могу получить его имя с помощью.sourcecontrol или .родитель?
2 ответа:
Вам не нужны массивы, просто используйте коллекцию элементов управления. Вместо установки родительского элемента управления, вероятно, следует добавить его в коллекцию:
'sSCTemp.Parent = Me Me.Controls.Add(sSCTemp)
Чтобы удалить их, вы можете ссылаться на них по свойству name:
If Me.Controls.ContainsKey("ShapeContainer1") Then Me.Controls.RemoveByKey("ShapeContainer1") End If
Элементы управления shape внутри ShapeContainer должны быть доступны через коллекцию Shape:
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 делает специальное примечание:
Будьте осторожны, чтобы не создавать более одного ShapeContainer для каждой формы или контейнера; это может привести к неожиданному поведению. Если вы добавляете строку времени разработки или элемент управления shape в форму или контейнер после написания кода для его создания программным способом, вы должны изменить этот код, чтобы использовать ShapeContainer, созданный дизайнером.
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