Custom UserControl Property used by child element

2019-01-20 16:14发布

I'm trying to get some WPF concepts down, so I've put together a simple example of what I'm trying to do. I would like to set a custom property of a user control, and have it be used by an element within the control.

I've been researching and experimenting, but I'm not fully understanding everything here. Any help would be appreciated.

The user control for this example is a simple square with a circle inside of it:

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

The VB Code Behind it:

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

When I use this user control, how can I apply a CircleColor to the control, and have it be shown as the Ellipse's fill color? Even better... can I give it a default color that shows up in the VS2008 Designer?

So... if I place one of these into my window XAML like this:

<app:CircleInSquare CircleColor="Blue" />

I would like the circle to display as Blue (or any other color I choose for that instance)

4条回答
聊天终结者
2楼-- · 2019-01-20 16:43

Set the DataContext for the ellipse to an instance of your CircleInSquare class. And make sure you use implement INotifyProperychanged on this class to make it property change enabled. check this link if you need more info on Propertychange

  <Ellipse Name="Circle"
             Margin="10"
             Fill="{Binding Path= CircleColor}"
             >
    </Ellipse>
查看更多
叛逆
3楼-- · 2019-01-20 16:56

Sorry to repost, but After re-reading you post, I think that you might be better off with templating. I've attached some samples in VB

Window.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>
查看更多
Root(大扎)
4楼-- · 2019-01-20 17:00

You set up a dependency property like this:

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

And then in your xaml you do something like this

Background="{TemplateBinding MouseOverBrush}"

and you can set a default style outside of the control template like this:

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

You might also be able to do it with a normal property but dependency properties support binding which makes styling much easier later.

HTH

查看更多
女痞
5楼-- · 2019-01-20 17:01

You need to create a DependencyProperty in your CircleInSquare class. Do some googling on that. The concept of using the property for your circle class like below is called AttachedProperties, and you will probably need to handle the CircleColorChanged event to do what you need.

<Ellipse app:CircleInSquare.CircleColor="Blue" />
查看更多
登录 后发表回答