diego.dona
diego.dona

Reputation: 11

Wpf Button with image - using Style/Template

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

Answers (2)

Grx70
Grx70

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

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

Related Questions