Передача значений в Style WPF – Apadtive solutions

Передача значений в Style WPF


Добавляем внешние свойства в стиль.

Для начала, чтобы передать картинку, нам нужно какое-то свойство. Можно использовать Tag, но это одноразовое решение, а нам надо много, так что навесим attached property, то есть класс extention, через который мы будем получать необходимые свойства:

static class ButtonExtensions
{
    public static ImageSource GetImage(DependencyObject obj)
    {
        return (ImageSource)obj.GetValue(ImageProperty);
    }

    public static void SetImage(DependencyObject obj, ImageSource value)
    {
        obj.SetValue(ImageProperty, value);
    }

    public static readonly DependencyProperty ImageProperty =
        DependencyProperty.RegisterAttached(
            "Image", typeof(ImageSource), typeof(ButtonExtensions));
}

Далее, наш стиль. Добавим картинку:

<Style TargetType="Button" x:Key="ButtonWithImage">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Height="75"
                    HorizontalAlignment="Stretch"
                    Background="#FF646464"
                    TextBlock.Foreground="White">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <Image Source="{Binding (local:ButtonExtensions.Image),
                                          RelativeSource={RelativeSource TemplatedParent}}"
                               Grid.Row="0"/>
                        <ContentPresenter
                            Content="{TemplateBinding Content}"
                            Grid.Row="1" HorizontalAlignment="Center"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

((local:ButtonExtensions.Image)— это синтаксис для привязки к attached property, local — это namespace.)

Используем в коде:

<Button Style="{StaticResource ButtonWithImage}"
        local:ButtonExtensions.Image="diskette.jpg">
    This is button content
</Button>

Всё!

Для случая ItemsControl , у меня работает так:

<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Style="{StaticResource ButtonWithImage}"
                    local:ButtonExtensions.Image="{Binding Image}">
                This is button content
            </Button>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
public class MyVM
{
    public string Image { get; }
    public MyVM(string imagePath) => Image = imagePath;
}
DataContext = new MyVM[] { new MyVM(@"diskette.jpg"), new MyVM(@"diskette.jpg") };