I defined a style in a ResourceDictionary
for a button with an image:
<Style x:Key="BotonIrAInicioStyle" TargetType="Button">
<Setter Property="Margin" Value="0"/>
<Setter Property="Width" Value="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}"/>
<Setter Property="Content">
<Setter.Value>
<Image Margin="2" Source="{StaticResource IconoDashboardBlanco}" MaxHeight="20" Stretch="Uniform"
RenderOptions.BitmapScalingMode="HighQuality"/>
</Setter.Value>
</Setter>
</Style>
The image source is defined in another ResourceDictionary
in the same assembly, and marked as x:Shared="False"
:
<BitmapImage x:Key="IconoDashboardBlanco" x:Shared="False"
UriSource="pack://application:,,,/QualityFramework;component/Images/dashboard64X64.png"/>
Since the style will be used in a different assembly, I used the "pack://application:,,,"
notation to reference the image. The Build Action
for the image is set to Resource (Do not copy to output directory)
.
In the main assembly I have two UserControls
which display a button with identical style:
<Button DockPanel.Dock="Left" Style="{StaticResource BotonIrAInicioStyle}" Click="BotonIrAInicio_Click"/> (Click event has nothing to do with the problem)
PROBLEM:
I open UserControl A
containing the button with the image and the image is displayed ok. Then I open UserControl B
containing an identical button, image ok. I open UserControl A
again, and the image is gone. Happens the same if I open UserControl B
and then UserControl A
, the last one "owns" the image.
I went everywhere and all the solutions point to the x:Shared="False"
, the URI notation
and the Build Action
... I applied all of them and the problem still happens. I also tried cleaning and rebuilding with no success.
What am I missing? Thanks!
PS: if I set the content of both buttons to the image directly it works ok, but the whole point of styling is to avoid exactly that!
The problem is not the BitmapImage
it's the content in the setter of the button - it's created once and thus has to "jump" between instances.
The easy, but not WPF-isque, solution is setting x:Shared="False"
on the style.
The correct way is to use ControlTemplate
or DataTemplate
.
From your observations:
"if I set the content of both buttons to the image directly it works ok" - this is because to do that you create two different instances of Image
object.
But, this: "the whole point of styling is to avoid exactly that!" is a misconception - styles are not meant to set the content of content controls, the content is dependent upon the context. If you have a visual that is repeating for all buttons (without dependency upon the content), it should reside in ControlTemplate
for the button. If you have a visual that is dependent upon the content (but the content is not the visual) it should reside in DataTemplate
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With