Question

I have a trivial custom control based on Button:

<Style TargetType="{x:Type local:ArrowButton}">

    <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
    <Setter Property="BorderBrush" Value="{StaticResource NormalBorderBrush}"/>
    <Setter Property="Focusable" Value="True"/>

    <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ArrowButton}">
                <Grid>
                    <Ellipse Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}"/>
                    <ContentPresenter/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

It does not have any significant C# code:

public class ArrowButton : Button, IDisposable
{
    static ArrowButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ArrowButton), new FrameworkPropertyMetadata(typeof(ArrowButton)));
    }
}

If I use this control (inside some UserControl) in the following way, it works fine (I got two buttons with black triangles):

    <Grid.Resources>
        <Style TargetType="local:ArrowButton">
            <Setter Property="Width" Value="30"/>
            <Setter Property="Height" Value="30"/>
        </Style>
    </Grid.Resources>

    <local:ArrowButton Grid.Column="0" HorizontalAlignment="Left">
        <Path HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" Data="M  0 0 L 0 20 L 10 10 Z"/>
    </local:ArrowButton>
    <local:ArrowButton Grid.Column="1" HorizontalAlignment="Right">
        <Path HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" Data="M  0 0 L 0 20 L 10 10 Z"/>
    </local:ArrowButton>

but if I move my Path to a StaticResource than I got a strange effect: only the last button has the black triangle and all other buttons on the UserConltrol remain empty (looks like the Path bound only once).

    <Grid.Resources>
    <Path x:Key="ArrowPath" Fill="Black" Data="M  0 0 L 0 20 L 10 10 Z"/>
    </Grid.Resources>

    <local:ArrowButton Content="{StaticResource ArrowPath}" Grid.Column="0" HorizontalAlignment="Left"/>
    <local:ArrowButton Content="{StaticResource ArrowPath}" Grid.Column="1" HorizontalAlignment="Left"/>

Any ideas, what could be wrong?

Was it helpful?

Solution

You'll need to use x:Shared="False" when declaring the Path resource:

<Path x:Key="ArrowPath" x:Shared="False" Fill="Black" Data="M  0 0 L 0 20 L 10 10 Z"/>

Otherwise, the same Path object will be used, which will change the Path's visual parent over and over again (until it stops for the last ArrowButton). Setting x:Shared="False" will create a new instance of the Path object each time it's consumed, which will solve your problem.

Make sure you also read the restrictions on where x:Shared can be used in WPF, listed at the bottom of the linked page.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top