-1

Let's say I have a lot of button declarations in WPF. These button declarations are very similar and vary only by one property. Here's some example code:

<Button x:Name="Button1"
        ...>
    <Image Source="{StaticResource ButtonImage}"
           Style="{StaticResource ButtonImageStyle}" />
</Button>

<Button x:Name="Button2"
        ...>
    <Image Source="{StaticResource ButtonImage}"
           Style="{StaticResource ButtonImageStyle}" />
</Button> 

<Button x:Name="Button3"
        ...>
    <Image Source="{StaticResource ButtonImage}"
           Style="{StaticResource ButtonImageStyle}" />
</Button> 

<Button x:Name="Button4"
        ...>
    <Image Source="{StaticResource ButtonImage}"
           Style="{StaticResource ButtonImageStyle}" />
</Button>

<Button x:Name="Button5"
        ...>
    <Image Source="{StaticResource ButtonImage}"
           Style="{StaticResource ButtonImageStyle}" />
</Button>

All these buttons look the same, they just vary by their name.

Since all the properties of the button are the same (except for the name) I created a style containing all the properties that are the same and used that style in all of my buttons.

<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="..." Value="..." />
</Style>

<Button x:Name="Button1"
        Style="{StaticResource ButtonStyle">
    <Image Source="{StaticResource ButtonImage}"
           Style="{StaticResource ButtonImageStyle}" />
</Button>

<Button x:Name="Button2"
        Style="{StaticResource ButtonStyle">
    <Image Source="{StaticResource ButtonImage}"
           Style="{StaticResource ButtonImageStyle}" />
</Button> 

<Button x:Name="Button3"
        Style="{StaticResource ButtonStyle">
    <Image Source="{StaticResource ButtonImage}"
           Style="{StaticResource ButtonImageStyle}" />
</Button> 

<Button x:Name="Button4"
        Style="{StaticResource ButtonStyle">
    <Image Source="{StaticResource ButtonImage}"
           Style="{StaticResource ButtonImageStyle}" />
</Button>

<Button x:Name="Button5"
        Style="{StaticResource ButtonStyle">
    <Image Source="{StaticResource ButtonImage}"
           Style="{StaticResource ButtonImageStyle}" />
</Button>

Everything works fine so far.

Now, since even the image is the same on all the buttons, I wanted to move this image to the style as well.

<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="..." Value="..." />
    <Setter Property="Content">
        <Setter.Value>
            <Image Source="{StaticResource ButtonImage}"
                   Style="{StaticResource ButtonImageStyle}" />
        </Setter.Value>
    </Setter>
</Style>

<Button x:Name="Button1"
        Style="{StaticResource ButtonStyle" />

<Button x:Name="Button2"
        Style="{StaticResource ButtonStyle" />

<Button x:Name="Button3"
        Style="{StaticResource ButtonStyle" />

<Button x:Name="Button4"
        Style="{StaticResource ButtonStyle" />

<Button x:Name="Button5"
        Style="{StaticResource ButtonStyle" />

But now I only see the image on the current active button, all the other buttons don't show the image. I guess with moving the image to the style it is only created in memory once and therefore it can be only shown once.

Is there a way to tell WPF, that an object created in a style should be created separately for every object that uses this style?

Nostromo
  • 1,177
  • 10
  • 28
  • I have previously offered an [explanation](https://stackoverflow.com/a/59263082/1506454) to similar question, but in your case I would suggest custom template for Button - Image included in template - like [this example](https://stackoverflow.com/q/18481787/1506454) – ASh Mar 23 '20 at 13:18
  • I thought about that myself but I wanted to avoid a custom template with all the triggers and stuff. – Nostromo Mar 23 '20 at 13:25

3 Answers3

0

You have to create each time new image, for it wouldn't be destroyed. So put x:Shared="false":

<Image x:Key="ButtonImage" x:Shared="false".. />

to the image resource definition, this should do th trick.

Rekshino
  • 6,954
  • 2
  • 19
  • 44
0

You could define the Image as a separate non-shared resource:

<Image x:Key="img" x:Shared="false" Source="{StaticResource ButtonImage}" 
    Style="{StaticResource ButtonImageStyle}" />
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Content" Value="{StaticResource img}" />
</Style>
mm8
  • 163,881
  • 10
  • 57
  • 88
-1

Thank you.

The x:Shared solution mentioned in two answers didn't work, at least not in the code I had to maintain.

But I found a ContentTemplate property with the button, and putting my Image inside a DataTemplate and putting this DataTemplate into my style worked for me.

Nostromo
  • 1,177
  • 10
  • 28