我有一个自定义控件(即从System.Windows.Control派生的类),我想为它设置一个默认样式。我知道可以通过创建themes / generic.xaml并在那里定义样式来实现。我之前已经这样做了并且它有效。
但是,因为样式相当简单(它只是一个允许快速模型的虚拟矩形),我想在仅代码中定义默认样式,以便我可以保持它接近类定义并避免文件杂乱与generic.xaml。这是我到目前为止所做的:
static Trailer()
{
// just there to be able to test it alternatively with generic.xaml
FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(Trailer), new FrameworkPropertyMetadata(typeof(Trailer)));
// define the template with dummy geometry
ControlTemplate DefaultTemplate = new ControlTemplate(typeof(Trailer));
FrameworkElementFactory rectFact = new FrameworkElementFactory(typeof(Rectangle));
rectFact.SetValue(Shape.FillProperty, new DynamicResourceExtension(SystemColors.ControlLightBrushKey));
DefaultTemplate.VisualTree = rectFact;
// define the style
Style DefaultStyle = new Style {TargetType = typeof (Trailer)};
Setter setter = new Setter();
setter.Property = Control.TemplateProperty;
setter.Value = DefaultTemplate;
DefaultStyle.Setters.Add(setter);
// register the style in application resources
Application.Current.Resources.Add(typeof(Trailer), DefaultStyle);
}
这适用于一个非常简单的测试应用程序,但是在控件保持为空(默认控件样式)的其他样式/模板的更复杂设置中失败。我还没有弄清楚导致干扰的原因,但我认为我没有用上面的代码实际设置我的Control的默认样式。
如果不是在应用程序资源中,我必须在哪里设置我的样式才能获得与generic.xaml相同的行为?
答案 0 :(得分:1)
在仔细思考这个问题并重述我(初学者)的依赖属性知识之后,我发现了一个简单的解决方案,我已经证明它可以工作。我只需要替换
Application.Current.Resources.Add(typeof(Trailer), defaultStyle);
通过
FrameworkElement.StyleProperty.OverrideMetadata(typeof(Trailer),
new FrameworkPropertyMetadata(defaultStyle));
这只是更改DependencyProperty默认值的官方方法!
我已经考虑过这个方向,但我的错误是我希望找到一个“DefaultStyleProperty”(与DefaultStylePropertyKey相对应...),但我没有想到更改更容易和更自然的可能性我的类的StyleProperty的默认值。
我很高兴微软的设计再次被证明是非常合乎逻辑且精心制作的(Amen ......)。
附录:我已经使用WPF检查器检查了可视化树。无论我是提供generic.xaml还是使用上面的代码方法,它们都是相同的。
作为一致性的附加功能,我添加了
FrameworkElement.OverridesDefaultStyleProperty.OverrideMetadata(typeof(Trailer),
new FrameworkPropertyMetadata(true));
这样可以保持默认样式不会从generic.xaml加载出来,如果它应该存在的话。既然我正在为自己设定风格,这实际上并没有什么区别。但要小心,我不确定这是否会导致不必要的副作用。