Решение основано на следующем подходе - содержимое кнопки определяется как ресурс, принадлежащий самой кнопке. К сожалению, ResourceKey не является DP и, следовательно, не может быть привязан, мы создали присоединенное свойство BindiableResourceKey, которое подменило его Пользовательский элемент управления имеет свойство ButtonLook типа string, которое содержит имя ресурса, который будет использоваться в качестве содержимого кнопки. Если вам нужно реализовать более сложную логику связывания, просто расширьте обработчик измененного значения присоединенного свойства.
Вот код:
Part1 - Управление пользователем:
<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>
Часть 2 - Прикрепленное имущество:
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);
}
}
Часть 3 - Потребитель:
<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>