WPF: reuse pattern for image buttons?

There are many image buttons in my WPF project, but since I did not find a way to do it correctly (I have to write the same triggers and style every time, the only difference is the image source), the resource dictionary has become very long. Is there a better way to do this?

Here is a sample style that I use for my buttons:

<Style x:Key="ButtonStyle" TargetType="{x:Type Button}"> <!-- Some setters --> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Grid> <Image Source="Images.png" Stretch="Fill"/> </Grid> <ControlTemplate.Triggers> <!-- Some triggers ( IsFocused, IsMouseOver, etc.) --> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> 

Thanks:)

+4
source share
3 answers

The easiest way is to create a special control with the Image property:

 public class ImageButton : Button { static ImageButton() { DefaultStyleKeyProperty.OverrideMetadata(typeof (ImageButton), new FrameworkPropertyMetadata(typeof (ImageButton))); } public ImageSource Image { get { return (ImageSource)GetValue(ImageProperty); } set { SetValue(ImageProperty, value); } } public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("Image", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource))); } 

Then you simply create a style for it in generic.xaml and bind to the Image property instead of explicitly setting the image:

 <Style x:Key="{x:Type my:ImageButton}" TargetType="{x:Type my:ImageButton}"> <!-- Some setters --> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type my:ImageButton}"> <Grid> <Image Source="{TemplateBinding Image}" Stretch="Fill"/> </Grid> <ControlTemplate.Triggers> <!-- Some triggers ( IsFocused, IsMouseOver, etc.) --> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> 

Then you can simply use it as follows:

 <my:ImageButton Image="Image.png" /> 

If you need more images for different button states, you can add more dependency properties to it.

Another possible approach is to use what I call a “parameterized style” to avoid creating a specific control; see this blog post for details.

+9
source

You can try to create a custom control that inherits from Button and use it as a TargetType in your template. Then you can use TemplateBinding in the image source.

 <Image Source="{TemplateBinding ImageSource}" Stretch="Fill"/> 

You will need to create an ImageSource property in your custom control. This way you can set the source to xaml, but you only need one resource template.

+1
source

You can use the BasedOn attribute as follows:

 <Style x:Key="BlueHighlightedButtonStyle" BasedOn="{StaticResource ButtonStyle}" TargetType="Button"> <Setter Property="Background" Value="DeepSkyBlue"/> </Style> 

This will make the button style with the same attributes as ButtonStyle, but with a DeepSkyBlue background.

0
source

Source: https://habr.com/ru/post/1499315/


All Articles