Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF UserControls: Image disappears even with 'x:Shared="False"'

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!

like image 389
Hannish Avatar asked Apr 27 '13 02:04

Hannish


1 Answers

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.

like image 102
XAMeLi Avatar answered Nov 15 '22 07:11

XAMeLi