Пользовательское свойство UserControl, используемое дочерним элементом

Я пытаюсь объяснить некоторые концепции WPF, поэтому я собрал простой пример того, что я пытаюсь сделать. Я хотел бы установить пользовательское свойство пользовательского элемента управления и использовать его элементом внутри элемента управления.

Я исследовал и экспериментировал, но я не полностью понимаю здесь все. Любая помощь будет оценена по достоинству.

Пользовательский элемент управления для этого примера представляет собой простой квадрат с кругом внутри:

<UserControl x:Class="CircleInSquare"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="100" Height="100" >
    <Grid Background="#000000">
        <Ellipse Name="Circle"
                 Margin="10"
                 Fill="?????????"
                 >
        </Ellipse>
    </Grid>
</UserControl>

Код VB за этим:

Partial Public Class CircleInSquare

    Private _CircleColor As Color

    Public Property CircleColor() As Color
        Get
            Return _CircleColor
        End Get
        Set(ByVal value As Color)
            _CircleColor = value
        End Set
    End Property

End Class

Когда я использую этот пользовательский элемент управления, как я могу применить CircleColor к элементу управления и показать его как цвет заливки эллипса? Еще лучше... могу ли я задать ему цвет по умолчанию, который отображается в конструкторе VS2008?

Итак... если я помещу один из них в свое окно XAML следующим образом:

<app:CircleInSquare CircleColor="Blue" />

Я хотел бы, чтобы круг отображался как синий (или любой другой цвет, который я выбираю для этого экземпляра)


person Ben Brandt    schedule 11.12.2008    source источник


Ответы (4)


Извините за репост, но после повторного прочтения вашего поста я думаю, что вам лучше использовать шаблоны. Я прикрепил несколько образцов в VB

Окно.xaml

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:WpfApplicationVB1"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <app:CircleInSquare Height="50" Width="50" CircleColor="Blue" SquareColor="Red"  />
    </Grid>
</Window>

CircleInSquare.xaml.vb

Partial Public Class CircleInSquare
    Public Property CircleColor() As Brush
        Get
            Return GetValue(CircleColorProperty)
        End Get

        Set(ByVal value As Brush)
            SetValue(CircleColorProperty, value)
        End Set
    End Property

    Public Shared ReadOnly CircleColorProperty As DependencyProperty = _
                           DependencyProperty.Register("CircleColor", _
                           GetType(Brush), GetType(CircleInSquare), _
                           New FrameworkPropertyMetadata(Brushes.Black))


    Public Property SquareColor() As Brush
        Get
            Return GetValue(SquareColorProperty)
        End Get

        Set(ByVal value As Brush)
            SetValue(SquareColorProperty, value)
        End Set
    End Property

    Public Shared ReadOnly SquareColorProperty As DependencyProperty = _
                           DependencyProperty.Register("SquareColor", _
                           GetType(Brush), GetType(CircleInSquare), _
                           New FrameworkPropertyMetadata(Brushes.Gray))

End Class

CircleInSquare.xaml

<UserControl x:Class="CircleInSquare"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:app="clr-namespace:WpfApplicationVB1"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <UserControl.Template>
        <ControlTemplate>
        <Border x:Name="PART_Square" Height="{TemplateBinding Height}"  Width="{TemplateBinding Width}" Background="{TemplateBinding app:CircleInSquare.SquareColor}">
        <Ellipse x:Name="PART_Ellipse" Height="{TemplateBinding Height}"
                 Width="{TemplateBinding Width}" Fill="{TemplateBinding app:CircleInSquare.CircleColor}" />
            </Border>
        </ControlTemplate>
    </UserControl.Template>
</UserControl>
person bendewey    schedule 11.12.2008
comment
Фантастический бендеви! Я возьму концепции и применю их к своему пользовательскому элементу управления. Я знаю, что это работает, но еще не понял, почему или почему использование шаблонов — лучший выбор. Если вы или кто-либо еще может объяснить достоинства шаблонов в такой ситуации, мы будем признательны :-) - person Ben Brandt; 12.12.2008
comment
Для меня это действительно сводится к тому, как вы собираетесь использовать контроль. В вашем случае вам нужно иметь гибкость в отношении содержимого элемента управления, и вы хотите предоставить содержимое элемента управления пользователям элемента управления. Шаблоны позволяют пользователям стилизовать ваше содержимое постфактум. - person bendewey; 12.12.2008
comment
Я бы использовал Binding для данных, когда вы хотите синхронизировать данные/содержимое одного свойства с другим свойством. Другой вариант прикрепленных свойств действительно лучше всего, когда вы хотите расширить поведение вашего элемента управления на элемент управления, находящийся вне вашего контроля. - person bendewey; 12.12.2008

Установите DataContext для эллипса на экземпляр вашего класса CircleInSquare. И убедитесь, что вы используете реализацию INotifyProperychanged для этого класса, чтобы разрешить изменение свойств. перейдите по этой ссылке, если вам нужна дополнительная информация об изменении свойств

  <Ellipse Name="Circle"
             Margin="10"
             Fill="{Binding Path= CircleColor}"
             >
    </Ellipse>
person Jobi Joy    schedule 11.12.2008

Вы настраиваете свойство зависимости следующим образом:

Public Shared ReadOnly MouseOverBrushProperty As DependencyProperty = DependencyProperty.Register("MouseOverBrush", GetType(Brush), GetType(BrushableComboBox), New UIPropertyMetadata())
Public Property MouseOverBrush() As Brush
    Get
        Return CType(GetValue(MouseOverBrushProperty), Brush)
    End Get
    Set(ByVal value As Brush)
        SetValue(MouseOverBrushProperty, value)
    End Set
End Property

И затем в вашем xaml вы делаете что-то вроде этого

Background="{TemplateBinding MouseOverBrush}"

и вы можете установить стиль по умолчанию вне шаблона элемента управления следующим образом:

<Style TargetType="{x:Type local:BrushableComboBox}">
    <Setter Property="MouseOverBrush" Value="Blue" />
    ...

Вы также можете сделать это с обычным свойством, но свойства зависимостей поддерживают привязку, что значительно упрощает стилизацию в дальнейшем.

ХТН

person Bryan Anderson    schedule 11.12.2008

Вам нужно создать DependencyProperty в вашем классе CircleInSquare. Погуглите об этом. Концепция использования свойства для вашего класса круга, как показано ниже, называется AttachedProperties, и вам, вероятно, потребуется обработать событие CircleColorChanged, чтобы сделать то, что вам нужно.

<Ellipse app:CircleInSquare.CircleColor="Blue" />
person bendewey    schedule 11.12.2008
comment
Я пытался поработать со свойствами зависимостей, но многие примеры, которые я нашел, были слишком сложными или неясными, или написанными на C#. Я пока не нашел хорошего простого примера, но буду продолжать экспериментировать. Я не был уверен, что это правильный путь, так как он не работал для меня. - person Ben Brandt; 11.12.2008
comment
Свойство зависимостей — это действительно то, что вам нужно. Возможно, есть и другие способы сделать это, но использование свойства зависимостей согласуется с общей философией WPF. Я бы привел пример, но я очень плохо разбираюсь в VB, а вам не нужен C#... - person Boyan; 11.12.2008
comment
вы знакомы с CodeSnippets. В VB есть фрагмент кода для свойств зависимостей (wpfdp, wpfdpa, wpfdpo) - person bendewey; 11.12.2008