覆盖WPF控件

use*_*155 2 c# wpf inheritance

我有一个来自第三方的WPF控件ParentWPFControl我想继承(让我们调用子类ChildWPFControl).在此过程中,我计划覆盖一些后端逻辑和前端样式的一部分.我可以做前者很好,但我做后者有问题.

我尝试为子国家/地区使用xaml < - > xaml.cs结构,但似乎不允许来自VS的以下警告:

Partial declarations of 'ChildWPFControl' must not specify different base classes
Run Code Online (Sandbox Code Playgroud)

现在,我想我可以编写一个ResourceDictionary XAML并在那里定义前端,但如果我想向XAML添加事件处理程序,这就成了问题(至少我找不到办法做到这一点)

我的另一个选择是直接在使用ChildWPFControl的对象中定义覆盖模板,但这使得设计更少模块化.

我能想到的最后一个选择是创建一个xaml < - > xaml.cs对,它是一个XAML样式容器,然后强制ChildWPFControl使用通过后端事件处理程序定义的ControlTemplate.

无论如何,我正在寻找的是一个优雅的模块化解决方案来解决我的问题.任何建议都会受到欢迎.

谢谢

dow*_*for 6

完全覆盖WPF控件需要几个步骤.有些是必要的,根据您的需要,有些是可选的.我将为您解释两个重要的问题:

创建新的默认样式

每个WPF控件都有一个默认样式,其中包含可视表示和覆盖属性.现在,如果你从控件派生WPF仍然认为你想使用这个默认样式,更改你在这样的静态构造函数中更改DefaultStyle

class MyButton : Button
{
    static MyButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton)));
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果您使用MyButton WPF尝试为MyButton查找样式,而不是为Button.OverridesDefaultStyle是一种风格的属性,在某些方面也可能很方便.通常这些默认样式应放在与主题相关的xaml中.

覆盖类时的事件处理程序

它是正确的 ControlTemplateStyle你不能使用像使用事件的句法糖Click="OnClick".关键是,视觉表示尽可能地与逻辑部分分离.使用OnApplyTemplate方法还有其他方法可以解决这个问题.通过覆盖它,您可以询问模板"给我这个控件",然后您只需在那里添加您的事件.

override OnApplyTemplate()
{
    var innerChild = Template.FindName("PART_InnerChild", this) as MyInnerControl;
    if(innerChild != null)
        innerChild.SomeEvent += OnSomeEvent;
}
Run Code Online (Sandbox Code Playgroud)

注意:这些控件的名称通常以PART_方式开头,这可以在WPF基本控件中看到.告诉设计师这是一个很好的方式"没有这个控制,逻辑部分可能会破坏".还有属性TemplatePart,但它并不重要,WPF并不关心它.AFAIK Expression混合使用它,我个人用它来告诉其他人什么样的内部控制对于使这个控制工作是绝对必要的.

个人建议

从类中派生通常是我们在尝试自定义控件时所做的最后一步.因为需要做大量工作才能使其完全正常工作并且可能会限制可重用性,所以我们尽量避免使用它,例如,除了模板覆盖和样式之外,还有一个很好的替代方案; 附加行为.

最后,整篇主题都包含在一篇很好的MSDN文章中.

希望有所帮助