开发者

Easy Dependency Property

开发者 https://www.devze.com 2023-03-30 05:53 出处:网络
I have a control which has a button named \"btn1\", and I want to change it\'s contents through a dependency property in xaml, like this:

I have a control which has a button named "btn1", and I want to change it's contents through a dependency property in xaml, like this:

<UserControl:UserControl1 ButtonContents="Something"/>

Here's what I have:

Public Class UserControl1 
    Public Shared ReadOnly ButtonContentsProperty As DependencyProperty =
        DependencyProperty.Register("ButtonContents",
                                    GetType(String),
                                    GetType(UserControl.UserControl1))

    Public Property ButtonContents() As Boolean
        Get
            Return GetValue(ButtonContentsProperty)
        End Get
        Set(ByVal value As Boolean)
            SetValue(ButtonContentsProperty, value)
        End Set
    End Property
End Class

But how can the depend开发者_开发技巧ency property know what to do?


The solution is based upon the following approach - button's content gets defined as a resource belonging to the button itself. Unfortunately ResourceKey is not a DP and hence cannot be bound, we created an attached property BindiableResourceKey which subsistutes for that. The user control has a property ButtonLook of string type which holds the name of the resource to be used as button's content. If you need to implement more complex linking logic just extend the attached property value changed handler.

Here's the code:

Part1 - User Control:

<UserControl x:Class="ButtonContentBinding.AControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" 
             d:DesignWidth="300"
             xmlns:local="clr-namespace:ButtonContentBinding">
    <Grid>
        <Button local:BindableResourceControl.ResourceKey="{Binding ButtonLook}">
            <Button.Resources>
                <Rectangle x:Key="BlueRectangle"
                    Width="40" Height="40" Fill="Blue" />
                <Rectangle x:Key="GreenRectangle"
                    Width="40" Height="40" Fill="Green" />
            </Button.Resources>
        </Button>
    </Grid>
</UserControl>

Part 2 - Attached Property:

public class BindableResourceControl : DependencyObject
    {
        public static readonly DependencyProperty ResourceKeyProperty =
            DependencyProperty.RegisterAttached("ResourceKey",
            typeof(string),
            typeof(BindableResourceControl),
            new PropertyMetadata((x, y) =>
            {
                ContentControl contentControl = x as ContentControl;

                if (x != null)
                {
                    contentControl.Content = contentControl.Resources[y.NewValue];
                }
            }));

        public static void SetResourceKey(DependencyObject x, string y)
        {
            x.SetValue(BindableResourceControl.ResourceKeyProperty, y);
        }

        public static string GetResourceKey(DependencyObject x)
        {
            return (string)x.GetValue(BindableResourceControl.ResourceKeyProperty);
        }
    }

Part 3 - Consumer:

<Window x:Class="ButtonContentBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:ButtonContentBinding">
    <Grid>
        <my:AControl ButtonLook="GreenRectangle"
                HorizontalAlignment="Left" Margin="0"      
                x:Name="aControl1" VerticalAlignment="Top" 
                Height="200" Width="200" />
    </Grid>
</Window>


When you register the property, you can also define a PropertyChangedCallback method where you can decide what to do when the property changes. More info here and here.


I would usually bind the value in the UserControl's XAML, e.g.

<UserControl ...
             Name="control">
    <!-- ... -->
    <Button Content="{Binding ButtonContents, ElementName=control}"/>
    <!-- ... -->
</UserControl>
0

精彩评论

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