Search code examples
c#wpftelerik

Style lost when another control with the same style loaded in WPF Application


In my WPF application, I am getting a strange behavior where the buttons lose the style at run time.

The buttons give up the style when another user control containing the buttons with the same style is loaded.

Here is the style definition in App.xaml:

   <Style x:Key="SaveButton" TargetType="telerik:RadButton">
        <Setter Property="Margin" Value="5"/>
        <Setter Property="Content">
            <Setter.Value>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Margin="5" Text="Save"/>
                    <Image Source="Resources\icons\save.png" Margin="5" 
                    Height="16" Width="16"></Image>
                </StackPanel>
            </Setter.Value>
        </Setter>
    </Style>

A window with a button carrying the style SaveButton is loaded properly. But from this window when another user control is loaded carrying one more button with the same style of SaveButton, User control button displays properly but the button on the window turns completely blank (no margins, no image, no text).

Any help in this regard is appreciated.


Solution

  • As you set the the Content property of the Button explicitly, its value can only be applied once. By default the XAML attribute x:Shared is set to true. This means that any given resource request always returns the same instance. In your case this means that each time the Styleis applied, the same value of ContentControl.Content is applied. To omit this, you have three options.

    The first option is to set the XAML attribute on the Style tag to False:

    <Style x:Shared=False ...></Style>

    The second option is to override the ControlTemplate of the Control:

    <Style ...>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Margin="5" Text="Save"/>
                        <Image Source="Resources\icons\save.png" Margin="5" 
                        Height="16" Width="16"></Image>
                    </StackPanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    The third option is to override the ContentControl.ContentTemplate directly:

    <Style ...">
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Margin="5" Text="Save"/>
                        <Image Source="Resources\icons\save.png" Margin="5" 
                        Height="16" Width="16"></Image>
                    </StackPanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>