Reputation: 11
I would like to have an image button for my Wpf application. At first i was happy with this answer i've found (WPF Button with Image).
However, now i want to make a style/template out of it, so i don't need to write the same thing over and over again.
The closest i could get was this image:
Image showing the three buttons i got so far
The problem is: I've lost the background (seems like there's nothing!). I already tried to get the background back with a Rectangle, but then, the button has no animations - there's no mouse over or click different colors. Seems like by using a template i erased it all...
That's not what i wanted to. I wanted to simply set a template and have all the default colors/animations.
This is my XAML so far:
<Style x:Key="btnSave" TargetType="{x:Type Button}">
<Setter Property="Width" Value="100"></Setter>
<Setter Property="Height" Value="25"></Setter>
<Setter Property="Margin" Value="5"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<StackPanel Orientation="Horizontal">
<Image Source="/Resources/save.png"></Image>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
What i wanted was to simply use it as:
<Button Style="{StaticResource btnSave}">Save File</Button>
And have a button with an image and default colors/animations.
Is there a simple way to do this? I don't want to mess with Triggers so far, all the links i've found about this try to teach how to make a full custom button.
Upvotes: 0
Views: 5315
Reputation: 10349
If you want to keep the default Button
template and only somewhat decorate it's content, your best bet is to facilitate the Button.ContentTemplate
property. Since it's a dependency property it can be styled/bound/etc. Here's how it could look in your case:
<Style x:Key="btnSave" TargetType="{x:Type Button}">
<Setter Property="Width" Value="100"></Setter>
<Setter Property="Height" Value="25"></Setter>
<Setter Property="Margin" Value="5"></Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="/Resources/save.png"></Image>
<ContentPresenter Content="{Binding}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
The only differences are that you use a DataTemplate
instead of ControlTemplate
and you need to bind the ContentPresenter.Content
property inside the template. Note that in this case we're templating the object being the value of Button.Content
, hence the binding has no path specified.
Upvotes: 1
Reputation: 37059
Easy: Use a ContentTemplate
, which templatizes just the content area of the Button
, not the whole thing. Button
supports that because it inherits from ContentControl
. Pretty much anything with a Content
property in WPF will support exactly the same thing.
The DataTemplate
in there has the control's Content
property for its DataContext
, so you bind the Content
simply with {Binding}
. And I took the liberty of giving the image a bit of a right margin, so it doesn't rub up against the regular button content.
<Style x:Key="btnSave" TargetType="{x:Type Button}">
<Setter Property="Width" Value="100"></Setter>
<Setter Property="Height" Value="25"></Setter>
<Setter Property="Margin" Value="5"></Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image
VerticalAlignment="Center"
Source="/Resources/save.png"
Margin="0,0,8,0"
/>
<ContentControl
Content="{Binding}"
VerticalAlignment="Center"
/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Upvotes: 0