User avatar
Matso
Topic Author
Posts: 13
Joined: 19 Jul 2018, 11:52

Image on a button

12 Mar 2019, 15:02

How to make a template of a button that contains an image, but the image should be configurable like the text on the button, using 'RelativeSource={RelativeSource TemplatedParent}' binding? What should I put the image source into on the level of a button to make it work? Is it possible to parameterize a button template in this way? Can I add a user property to a button to pass the image source I want?

MK
 
User avatar
stonstad
Posts: 241
Joined: 06 Jun 2016, 18:14
Location: Lesser Magellanic Cloud
Contact:

Re: Image on a button

12 Mar 2019, 15:14

Hi Matso -- this is what I am doing. The experts here might have a better way.
    
    <!-- Button Templates and Styles -->
    <ControlTemplate x:Key="ImageButtonTemplate" TargetType="Button">
        <Grid>
            <Image x:Name="PART_Image" Stretch="None"/>
            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{DynamicResource _ContentPresenterMargin}"/>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="False">
                <Setter TargetName="PART_Image" Property="Source" Value="{DynamicResource _UpImage}"/>
            </Trigger>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter TargetName="PART_Image" Property="Source" Value="{DynamicResource _OverImage}"/>
            </Trigger>
            <Trigger Property="IsFocused" Value="True">
                <Setter TargetName="PART_Image" Property="Source" Value="{DynamicResource _OverImage}"/>
            </Trigger>
            <Trigger Property="IsPressed" Value="True">
                <Setter TargetName="PART_Image" Property="Source" Value="{DynamicResource _DownImage}"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
                <Setter TargetName="PART_Image" Property="Source" Value="{DynamicResource _DisabledImage}"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <Style x:Key="ButtonWideStyle" TargetType="{x:Type Button}">
        <Style.Resources>
            <BitmapImage x:Key="_UpImage" UriSource="Controls/Buttons/buttonwide_up.png"/>
            <BitmapImage x:Key="_DownImage" UriSource="Controls/Buttons/buttonwide_down.png"/>
            <BitmapImage x:Key="_OverImage" UriSource="Controls/Buttons/buttonwide_over.png"/>
            <BitmapImage x:Key="_DisabledImage" UriSource="Controls/Buttons/buttonwide_up.png"/>
        </Style.Resources>
        <Setter Property="Template" Value="{StaticResource ImageButtonTemplate}"/>
        <Setter Property="FontSize" Value="22"/>
        <Setter Property="Foreground" Value="White"/>
    </Style>
 
User avatar
Matso
Topic Author
Posts: 13
Joined: 19 Jul 2018, 11:52

Re: Image on a button

12 Mar 2019, 16:15

Funny thing is that, when I put a path to an image in the buttons 'Content' property, and hook it up to the actual image in the template this way:
<Image x:Name="icon" HorizontalAlignment="Stretch" Height="70" Margin="0" VerticalAlignment="Stretch" Width="70" Source="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}"/>
It works! :D xD

The image is not visible in VS Blend though.

MK
 
User avatar
sfernandez
Site Admin
Posts: 2984
Joined: 22 Dec 2011, 19:20

Re: Image on a button

13 Mar 2019, 00:27

Using DynamicResources as @stonstad explained is an easy (only xaml) way to achieve that. You can also define the template in a base style, and then extend that style for different buttons using different images:
<Style x:Key="BaseButtonStyle" TargetType="Button">
  <Setter Property="Template"> ... </Setter>
</Style>

<Style x:Key="OkButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
  <Style.Resources>
    <BitmapImage x:Key="_UpImage" UriSource="Controls/Buttons/ok_up.png"/>
    <BitmapImage x:Key="_DownImage" UriSource="Controls/Buttons/ok_down.png"/>
    <BitmapImage x:Key="_OverImage" UriSource="Controls/Buttons/ok_over.png"/>
    <BitmapImage x:Key="_DisabledImage" UriSource="Controls/Buttons/ok_up.png"/>
  </Style.Resources>
</Style>

<Style x:Key="CancelButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
  ...
</Style>
Another option would be defining a set of attached properties to specify the images directly in each button, and then bind these properties from the template. That will allow you to use a single style:
<Button
  local:ButtonImages.UpImage="Controls/Buttons/ok_up.png"
  local:ButtonImages.DownImage="Controls/Buttons/ok_down.png"
  ... />
<Button
  local:ButtonImages.UpImage="Controls/Buttons/cancel_up.png"
  local:ButtonImages.DownImage="Controls/Buttons/cancel_down.png"
  ... />

Who is online

Users browsing this forum: No registered users and 85 guests