2014-11-05 61 views
1

我有一个窗口的基类,其中包含许多这类窗口常见的事件处理程序(它们激发常用的验证方法)。从xaml的父类附加事件处理程序

下面是一个例子事件处理程序:

protected virtual void ValidateTextBoxTextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) 
{ 
    ValidateProperty((FrameworkElement)sender, TextBox.TextProperty); 
} 

并有大约20的这些,覆盖公共控件。

每个窗口实例都是从基类的子类构建的。在子类的.xaml我做的:

<TextBox 
    TextChanged="ValidateTextBoxTextChanged"/> 

但是,当我浏览到这个窗口,我得到以下错误:

Failed to assign to property 'System.Windows.Controls.TextBox.TextChanged'.

所以它没有找到事件处理程序。有没有一种优雅的方式可以分配事件处理程序,而不需要在每个子类中重复它们(约30个孩子和计数)?

+0

请显示一个更完整的代码示例。至少,它需要显示完整的上下文,即该方法在哪个类中,该类如何与您的XAML相关联,当然也包括XAML本身中的上下文。请参阅http://stackoverflow.com/help/mcve – 2014-11-05 17:33:37

回答

3

这很有趣 - 它似乎是事件机制的局限性,只检查部分代码隐藏类,而不是它的基类。 (此问题也已被提出herehere。)我想不出一个理想的解决方法。

当然,你可以通过把虚拟覆盖在每个子类中修复错误:

protected override void ValidateTextBoxTextChanged(object sender, TextChangedEventArgs e) 
{ 
    base.ValidateTextBoxTextChanged(sender, e); 
} 

现在,理所当然地认为,似乎是一个麻烦。另一种方法是使用触发器/动作组合来调用基类方法:

<TextBox> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="TextChanged"> 
      <ei:CallMethodAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType=local:BaseWindow}}" MethodName="ValidateTextBoxTextChanged" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
</TextBox> 

为此,您需要使该方法公开。您可以使用上述变体来简化语法并减少绑定数量:使用附加属性应用触发器,并将验证方法置于静态资源中,并带有可选的覆盖。


另一种可能的方法是继承TextBox本身,并把您的验证逻辑存在。您可以公开一个依赖项属性,以允许扩展TextBox的实例覆盖默认验证逻辑。

0

我得到了这个代码工作。我有一个具有几descendats

<Page x:Class="mycls"><Button x:Name="mybrn"/></Page> 

继承其基本XAML页面和一些观点:

<local:mycls x:Class="mychild"></local:mycls> 

如果我分配在XAML监听器,它并没有在子视图中工作。但在代码隐藏它的工作原理:

public mycls() 
{ 
    InitializeComponent() 
    (this.FindName("mybtn") as Button).Click += mybtn_click; 
} 

在此子视图“inhherit”也处理程序。

相关问题