Why doesn't DefaultStyleKey change the default

2019-07-02 20:13发布

I have a base class called Handle from which I derive several base classes such as RectHandle and EllipseHandle. In those subclasses I have attempted to override the default style key to point to Handle but a style targeting Handle is not applied. I still have to explicitly target RectHandle or EllipseHandle either directly, or via a 'BasedOn' style. What am I missing?

Here's the MSDN excerpt for DefaultStyleKeyProperty:

A control typically overrides the default value of this property to be its own type, but in some cases could also use a base type for which a style in the theme dictionaries exists.

Here's my code

public abstract class Handle : Shape
{
    static Handle()
    {
        WidthProperty.OverrideMetadata(
            typeof(Handle),
            new FrameworkPropertyMetadata(10.0));

        HeightProperty.OverrideMetadata(
            typeof(Handle),
            new FrameworkPropertyMetadata(10.0));

        FillProperty.OverrideMetadata(
            typeof(Handle),
            new FrameworkPropertyMetadata(Brushes.Yellow));

        StrokeProperty.OverrideMetadata(
            typeof(Handle),
            new FrameworkPropertyMetadata(Brushes.Gray));

        StrokeThicknessProperty.OverrideMetadata(
            typeof(Handle),
            new FrameworkPropertyMetadata(2.0));
    }
}

public class RectHandle : Handle
{
    static RectHandle()
    {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof(RectHandle),
            new FrameworkPropertyMetadata(typeof(Handle)));
    }

    protected override Geometry DefiningGeometry
    {
        get
        {
            var origin = new Point(-RenderSize.Width / 2, -RenderSize.Height / 2);
            var rect = new Rect(origin, RenderSize);
            return new RectangleGeometry(rect);
        }
    }
}

public class EllipseHandle : Handle
{
    static RectHandle()
    {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof(EllipseHandle),
            new FrameworkPropertyMetadata(typeof(Handle)));
    }

    protected override Geometry DefiningGeometry
    {
        get
        {
            var origin = new Point(-RenderSize.Width / 2, -RenderSize.Height / 2);
            var rect = new Rect(origin, RenderSize);
            return new EllipseGeometry(rect);
        }
    }
}

And the style...

<Style TargetType="{x:Type annotations:Handle}">
    <Setter Property="Stroke" Value="Red" />
</Style>

Again, this doesn't work.

My work-around is to create two other styles based on the first, but I thought that was the entire point of the DefaultStyleKey property.

<Style TargetType="{x:Type annotations:Handle}">
    <Setter Property="Stroke" Value="Red" />
</Style>

<Style TargetType="{x:Type annotations:RectHandle}"
    BasedOn="{StaticResource {x:Type annotations:Handle}}" />

<Style TargetType="{x:Type annotations:EllipseHandle}"
    BasedOn="{StaticResource {x:Type annotations:Handle}}" />

标签: c# wpf default
1条回答
Animai°情兽
2楼-- · 2019-07-02 20:28

I figured it out. The DefaultStyleKey property only refers to styles defined in a theme, or in Generic.xaml under Themes. If I move my Handle style there, all of a sudden, it works. If I instead copy it local to the window, which I had done, it doesn't. Interesting that the lookups are different.

查看更多
登录 后发表回答