从xaml中的父类附加事件处理程序

时间:2014-11-05 14:14:13

标签: c# xaml silverlight events inheritance

我有一个窗口的基类,其中包含许多常用于此类窗口的事件处理程序(它们触发常用的验证方法)。

以下是一个示例事件处理程序:

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

并且大约有20个,涵盖了共同控制。

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

<TextBox 
    TextChanged="ValidateTextBoxTextChanged"/>

但是当我导航到这个窗口时,我收到以下错误:

  

无法分配属性'System.Windows.Controls.TextBox.TextChanged'。

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

2 个答案:

答案 0 :(得分: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的实例覆盖默认验证逻辑。

答案 1 :(得分:0)

我在代码中使用了这个。我有一个基本的xaml页面,几乎没有下降

docker logs <container-name>

一些继承它的观点:

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

如果我在xaml中分配监听器,它在子视图中不起作用。但是在代码隐藏中它起作用:

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

在这个子视图之后,“inhherit”也是一个处理程序。