用户控件,自定义控件,继承和覆盖

时间:2012-08-03 14:00:36

标签: wpf wpf-controls

我知道这个问题可能会得到很多“重复问题”的评论,但我还没有看到一个答案有效或不简单“不惜一切代价避免它”。但是,我已经创建了一个控件,让我们在名为“ControlA_Project”的项目中将其称为“ControlA”,我打算在名为“ControlB”的控件中覆盖其中的一些虚拟方法,该控件在另一个名为“ControlA”的项目中继承“ControlA” ControlB_Project“。我认为“ControlA”有保存和加载方法,我希望从保存和加载到文件,保存和加载到数据库(如果以后需要另一个保存和加载类型,我可以再次覆盖这些方法) 。  我遇到的问题是我最初使用“ControlA”作为用户控件,当我尝试将新控件与覆盖(“ControlB”)添加到窗口时,我会收到此错误:

组件'ControlB_Project.ControlB'没有由URI'/ControlA_Project ;component/usercontrols/ControlA.xaml'标识的资源。

谷歌搜索错误我得出结论你不能从用户控件继承(或为了争论它不是一个好主意)。所以我然后将控件从用户控件更改为自定义控件。然而,这导致我另一个问题,控件的模板没有链接到后面的代码(即On_Click),就像它在用户控件中一样,没有简单的方法来简单地覆盖行为(据我所知) 。我知道我可以通过复制和粘贴ControlAs模板并更改几行来重新控制ControlB,但是controlA有一个大模板,并且制作多个副本似乎是浪费空间。  那么简单来说就是有一种正确的方法来改变wpf中控件的行为吗?

1 个答案:

答案 0 :(得分:2)

首先,请记住用户可以更改ControlTemplate,因此您需要确保清楚地标记重要字段。 所以,如果你想要一个OnClick事件。首先将您的按钮标记为“重要”

<Button x:Name="PART_MyButton"/>

在你的控制类上标记这个也是一个好主意

[TemplatePart(Name = "PART_MyButton", Type = typeof(Button))]
public class MyCustomControl : Control

现在您要附加到该按钮的点击事件来执行此操作,覆盖OnApplyTemplate方法。

public override void OnApplyTemplate()
{
    mButton = Template.FindName("PART_MyButton", this) as Button;
    mButton.Click += MyEventHandler;
}

根据您的控件在没有控件的情况下的工作情况,您应该优雅地处理未找到的控件或抛出异常。

最后一件事是。如果覆盖具有默认样式的控件,则提供新的默认样式可能是个好主意。

static MyCustomControl()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
}

并在generic.xaml

中添加隐式样式