【发布时间】:2014-03-23 15:17:53
【问题描述】:
我创建了一个自定义控件 (CartesianCanvas),它在添加任何子元素时存储它的一些属性。为此,我创建了一个新的集合属性 (ItemsInfo) 并覆盖了 OnVisualChildrenChanged,以便在添加或删除子项时,从集合属性中添加或删除相应的属性。
但是,当我通过 XAML 将子项添加到控件时,似乎在设置属性之前调用了 OnVisualChildrenChanged,因为所有属性都有其默认值。在加载窗口后添加子项时,情况并非如此。如何确保在调用 OnVisualChildrenChanged 时设置了孩子的属性?
这是我的代码:
Public ReadOnly Property ItemsInfo As Collection(Of CartesianInfo)
Get
Return DirectCast(GetValue(ItemsInfoProperty), Collection(Of CartesianInfo))
End Get
End Property
Friend Shared ReadOnly ItemsInfoKey As System.Windows.DependencyPropertyKey = System.Windows.DependencyProperty.RegisterReadOnly("ItemsInfo", GetType(Collection(Of CartesianInfo)), GetType(CartesianCanvas), New System.Windows.PropertyMetadata(New Collection(Of CartesianInfo)))
Public Shared ReadOnly ItemsInfoProperty As DependencyProperty = ItemsInfoKey.DependencyProperty
Protected Overrides Sub OnVisualChildrenChanged(visualAdded As DependencyObject, visualRemoved As DependencyObject)
Try
If Not visualAdded Is Nothing Then
If Not GetType(FrameworkElement).IsAssignableFrom(visualAdded.GetType) Then
Me.Children.Remove(visualAdded)
Throw New Exception("The object added:" & visualAdded.ToString & " was not of type or decended from: FrameworkElement and so was removed from CartesianCanvas")
Else
AddItemInfo(visualAdded)
End If
End If
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
If Not visualRemoved Is Nothing Then
RemoveItemInfo(visualRemoved)
End If
MyBase.OnVisualChildrenChanged(visualAdded, visualRemoved)
End Sub
Private Sub AddItemInfo(ByRef item As FrameworkElement)
Dim itemsInfoCollection As New Collection(Of CartesianInfo)
itemsInfoCollection = ItemsInfo
Dim ItemXCoordinate As Double
Dim ItemYCoordinate As Double
Dim ItemCalculateFromVerticalCenter As Boolean
Dim ItemCalculateFromHorizontalCenter As Boolean
If Double.IsNaN(Canvas.GetLeft(item)) Then
Canvas.SetLeft(item, 0)
End If
If Double.IsNaN(Canvas.GetTop(item)) Then
Canvas.SetTop(item, 0)
End If
ItemXCoordinate = Canvas.GetLeft(item)
ItemYCoordinate = Canvas.GetTop(item)
If item.VerticalAlignment = Windows.VerticalAlignment.Center Then
ItemCalculateFromVerticalCenter = True
End If
If item.HorizontalAlignment = Windows.HorizontalAlignment.Center Then
ItemCalculateFromHorizontalCenter = True
End If
ItemsInfo.Add(New CartesianInfo(item, ItemXCoordinate, ItemYCoordinate, ItemCalculateFromVerticalCenter, ItemCalculateFromHorizontalCenter))
SetValue(ItemsInfoKey, ItemsInfo)
PositionChild(item)
End Sub
这是我的 XAML
<local:CartesianCanvas x:Name="MainCanvas">
<Button Width="50" Height="100" Canvas.Top="100" Canvas.Left="20"
Content="test" Click="Button_Click"/>
</local:CartesianCanvas>
【问题讨论】:
标签: wpf xaml custom-controls dependency-properties