Easy Dependency Property
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>
精彩评论