问题
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}}" />
回答1:
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.
来源:https://stackoverflow.com/questions/32956005/why-doesnt-defaultstylekey-change-the-default-style-for-my-subclasses