Пользовательская панель WPF 4.0 не отображает динамически добавленные элементы управления в VS 2010 Designer - PullRequest
0 голосов
/ 17 января 2011

У меня есть пользовательский элемент управления панели, в котором я пытаюсь динамически добавлять элементы управления.Когда я запускаю приложение, статические и динамически добавленные элементы управления отображаются идеально, но динамические элементы управления не отображаются в визуальном дизайнере студии.Появляются только элементы управления, размещенные декларативно в 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>

Ответы [ 2 ]

1 голос
/ 17 января 2011

Я понял это благодаря некоторым подсказкам, которые дал мне Бенджамин.Похоже, вам нужно загружать динамически добавленные элементы управления в обработчик событий 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
1 голос
/ 17 января 2011

Я только что попробовал ваш код в Visual Studio 2008 Standard Edition, и Panel появляется в конструкторе (см. Снимок экрана ниже).

alt text

На снимке экрана показано

Вы пытались пересобрать свой проект, закрыть окно XAML и снова открыть его, чтобы дизайнер мог перезагрузить?

Редактировать: просто чтобы уточнить комментарий ниже, кнопка была добавлена ​​вОднако XAML, если я удаляю кнопку, это вывод, который я получаю в конструкторе Visual Studio.

alt text

Это 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>
...