我有一个自定义面板控件,我正在尝试动态添加控件。当我运行应用程序时,静态和动态添加的控件显示完美,但动态控件不会出现在visual studio设计器中。仅出现在XAML中以声明方式放置的控件。我目前正在CreateUIElementCollection覆盖中添加动态控件,但我也在构造函数中尝试了这个但没有成功。
Public Class CustomPanel1
Inherits Panel
Public Sub New()
End Sub
Protected Overrides Function MeasureOverride(ByVal availableSize As System.Windows.Size) As System.Windows.Size
Dim returnValue As New Size(0, 0)
For Each child As UIElement In Children
child.Measure(availableSize)
returnValue.Width = Math.Max(returnValue.Width, child.DesiredSize.Width)
returnValue.Height = Math.Max(returnValue.Height, child.DesiredSize.Height)
Next
returnValue.Width = If(Double.IsPositiveInfinity(availableSize.Width), returnValue.Width, availableSize.Width)
returnValue.Height = If(Double.IsPositiveInfinity(availableSize.Height), returnValue.Height, availableSize.Height)
Return returnValue
End Function
Protected Overrides Function ArrangeOverride(ByVal finalSize As System.Windows.Size) As System.Windows.Size
Dim currentHeight As Integer
For Each child As UIElement In Children
child.Arrange(New Rect(0, currentHeight, child.DesiredSize.Width, child.DesiredSize.Height))
currentHeight += child.DesiredSize.Height
Next
Return finalSize
End Function
Protected Overrides Function CreateUIElementCollection(ByVal logicalParent As System.Windows.FrameworkElement) As System.Windows.Controls.UIElementCollection
Dim returnValue As UIElementCollection = MyBase.CreateUIElementCollection(logicalParent)
returnValue.Add(New TextBlock With {.Text = "Hello, World!"})
Return returnValue
End Function
Protected Overrides Sub OnPropertyChanged(ByVal e As System.Windows.DependencyPropertyChangedEventArgs)
MyBase.OnPropertyChanged(e)
End Sub
End Class
我对这个自定义面板的使用
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomPanel"
Title="MainWindow" Height="364" Width="434">
<local:CustomPanel1>
<CheckBox />
<RadioButton />
</local:CustomPanel1>
</Window>
答案 0 :(得分:1)
我刚刚在Visual Studio 2008 Standard Edition中尝试过您的代码,而Panel正在设计器中显示(参见下面的屏幕截图)。
屏幕截图显示
您是否尝试重新构建项目,关闭XAML窗口并再次打开它以便设计人员可以重新加载?
编辑:为了澄清下面的评论,该按钮已在XAML中添加,但如果我删除该按钮,则这是我在Visual Studio设计器中获得的输出。
这是我用来获得此输出的XAML:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="Window1" Height="300" Width="300">
<local:CustomPanel1>
</local:CustomPanel1>
</Window>
答案 1 :(得分:1)
由于本杰明给我的一些暗示,我想通了。看起来您需要在UIElement.Loaded事件处理程序中加载动态添加的控件。在此事件发生之前,设计者显然会覆盖Children集合中的值。这是解决问题的代码:
Public Class CustomPanel1
Inherits Panel
Private _text As TextBlock
Public Sub New()
End Sub
Protected Overrides Function MeasureOverride(ByVal availableSize As System.Windows.Size) As System.Windows.Size
Dim returnValue As New Size(availableSize.Width, availableSize.Height)
If _text IsNot Nothing Then
For Each child As UIElement In Children
child.Measure(availableSize)
returnValue.Width = Math.Max(returnValue.Width, child.DesiredSize.Width)
returnValue.Height = Math.Max(returnValue.Height, child.DesiredSize.Height)
Next
returnValue.Width = If(Double.IsPositiveInfinity(availableSize.Width), returnValue.Width, availableSize.Width)
returnValue.Height = If(Double.IsPositiveInfinity(availableSize.Height), returnValue.Height, availableSize.Height)
End If
Return returnValue
End Function
Protected Overrides Function ArrangeOverride(ByVal finalSize As System.Windows.Size) As System.Windows.Size
If _text IsNot Nothing Then
Dim currentHeight As Integer
For Each child As UIElement In Children
child.Arrange(New Rect(0, currentHeight, child.DesiredSize.Width, child.DesiredSize.Height))
currentHeight += child.DesiredSize.Height
Next
End If
Return finalSize
End Function
Private Sub CustomPanel1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
_text = New TextBlock With {.Text = "Hello, World!"}
Children.Add(_text)
End Sub
End Class