'Display image in content presenter in button

I have a button with a style that displays an image inside it. I would like to be able to specify the image it uses using the Content property on the button (or some other means).

How can accomplish this without actually nesting an image directly in the button.

<BitmapImage x:Key="closeImage" UriSource="close.png" />

I thought I could maybe specify the image file name like so:

<Button Content="{{StaticResource closeImage}" x:Name="closeButton" Click="closeButton_Click" Style="{DynamicResource WindowToolboxButton}"/>

Style:

    <Style x:Key="WindowToolboxButton" TargetType="{x:Type Button}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
        <Setter Property="Background" Value="{StaticResource ButtonNormalBackgroundFill}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ButtonBorder}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid x:Name="grid" Height="15" Width="15">
                        <Border x:Name="border" CornerRadius="2,2,2,2" BorderBrush="#FFBBCDD2" BorderThickness="1" Opacity="0" Margin="0">
                            <Border.Background>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="#FF82A3AC" Offset="1"/>
                                    <GradientStop Color="#7FCDD9DC"/>
                                </LinearGradientBrush>
                            </Border.Background>
                        </Border>
                        <Image x:Name="image" Source="close.png" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center" >

                        </Image>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


Solution 1:[1]

I'm pretty sure I'm missing the problem of your question, but the following code works for me:

<Window.Resources>
 <Image x:Key="test" Source="/Images/ChangeCase.png"/>
</Window.Resources>

<!-- Using a Resource for the Content -->
<Button Width="100" Height="20" Content="{StaticResource test}"/>

<!-- Specifying the Content directly -->
<Button Width="100" Height="20">
 <Image Source="/Images/ChangeCase.png"/>
</Button>

Plus I spotted an error in your code:

<Button Content="{{StaticResource closeImage}" [...]

should be:

<Button Content="{StaticResource closeImage}" [...]

I don't quite understand what your style is doing. Why do you have the Content Property set to a StaticResource when you want to specify the image via style?

Edit:

Alright, I tried your style and it also works for me.

   <Style x:Key="WindowToolboxButton" TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid x:Name="grid" Height="15" Width="15">
                        <Border x:Name="border" CornerRadius="2,2,2,2" BorderBrush="#FFBBCDD2" BorderThickness="1" Opacity="0" Margin="0">
                            <Border.Background>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="#FF82A3AC" Offset="1"/>
                                    <GradientStop Color="#7FCDD9DC"/>
                                </LinearGradientBrush>
                            </Border.Background>
                        </Border>
                        <Image x:Name="image" Source="/Images/ChangeCase.png" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

  <Button Width="100" Height="20" Content="Test" Style="{DynamicResource WindowToolboxButton}"/>

The image is shown. However, I can't see your border due to the opacity-prop being set to 0.

The content that is given directly on the button is overriden by the style.

Maybe there is sth wrong with your image? Did you set its build-property to Resource?

Solution 2:[2]

I think the correct way of doing this is

  1. Create a new custom control ImageButton which derives from Button
  2. Create a DP 'ImageSource' of type 'ImageSource' in ImageButton and in its style bind the Source of the Image to this DP.

Then you can use it like <ImageButton ImageSource={StaticResource ...}/>

If you try to add an image defined in a resource to a content control it will only work the first time. The second time you try to add the same image into another content control it will fail with "Specified visual is already a child of another visual..."

Solution 3:[3]

Actually, this is really easy. Use the Style you already have and add the following to 'image'

Source="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}"

Then (as long as you have the image set as Content/Copy if newer) you can set the Content with the desired image's Uri.

<Button Content="/[projectname];component/.../close.png" Style="{StaticResource WindowToolboxButton}" ... />

note: replace '[projectname]' with your project's name and the '...' with path to the image

Solution 4:[4]

Replace

<Image x:Name="image" Source="close.png" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center" >

With

<Image x:Name="image" Source="{Binding Content, RelativeSource={RelativeSource AncestorType=Button}" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center" >

Where your ancestor type will be That button that is called in xaml, and there you can Set Content of that button to point to some image.

Example:

<cc:customButton  Content={StaticResource someImage}.../>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 NVM
Solution 3 Murkaeus
Solution 4