开发者

WPF 4.0 Custom panel won't show dynamically added controls in VS 2010 Designer

I have a custom panel control that I'm trying to dynamically add controls within. When I run the application the static and dynamically added controls show up perfectly, but the dynamic controls do not appear within the visual studio designer. Only the controls placed declaratively in the XAML appear. I'm currently adding the dynamic control in the CreateUIElementColl开发者_Go百科ection override, but I've also tried this in the constructor without success.

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

And my usage of this custom panel

<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>


I have just tried your code in Visual Studio 2008 Standard Edition and the Panel is showing up in the designer (see screen shot below).

WPF 4.0 Custom panel won't show dynamically added controls in VS 2010 Designer

The screenshot shows

Have you tried re-building your project, closing the XAML window and opening it again so that the designer can reload?

Edit: Just to clarify on the comment below, the button was added in XAML however if I remove the button this is the output I am getting in the Visual Studio designer.

WPF 4.0 Custom panel won't show dynamically added controls in VS 2010 Designer

This is the XAML I used to get this output:

<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>


I figured it out thanks to some hints that Benjamin gave me. Looks like you need to load dynamically added controls in the UIElement.Loaded event handler. The designer apparently overwrites the values within the Children collection before this event occurs. Here's the code that fixed the issue:

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜