我有一个窗口的基类,其中包含许多常用于此类窗口的事件处理程序(它们触发常用的验证方法)。
以下是一个示例事件处理程序:
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个孩子和计数)?
答案 0 :(得分:3)
这很有趣 - 似乎只是检查部分代码隐藏类而不是其基类的事件机制的限制。 (此问题也已提出here和here。)我也想不出理想的解决方法。
当然,您可以通过在每个子类中放置一个虚拟覆盖来修复错误:
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”也是一个处理程序。