Добавляем внешние свойства в стиль.
Для начала, чтобы передать картинку, нам нужно какое-то свойство. Можно использовать 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") };