问题是KeyDown
事件被触发两次,第一次来自CustomTextBox
内名为textSource
的{{1}};第二个,来自名为Style
的{{1}}中的控制。
linked问题提供了一个解决方案,您可以在其中过滤EventHandler MainWindow
来源"CTbox"
工作正常:
OnKeyDown
基本上我想知道是否有更好的解决方案,如果有人能解释为什么会发生这种情况以及如何避免它。
该样式意味着在e.Source != "textSource"
中创建提示文字或WaterMark,而无需转发if (e.Source is CustomTextBox sourceTextBox && sourceTextBox.Name.Equals("textSource"))
{
return;
}
提前致谢。
按照代码创建此行为的最小,完整和可验证的示例
CustomTextBox
Focus events
答案 0 :(得分:1)
因此,您将获得两次OnKeyDown处理程序的执行,因为您的XAML实际上是在CustomTextBox中构建CustomTextBox。使用routing strategy WPF事件和您的可视化树看起来像这样:
KeyDown事件自然会在两个地方触发(textsource,然后冒泡到CustomTextBox)。旁注,如果你覆盖OnPreviewKeyDown,你应该得到相反的顺序 - CTbox隧道向下到textSource。
要回答你问题的第二部分 - 如何避免这种情况,我想也许你应该重新考虑你的实现。我的问题是:
编辑评论 鉴于您的澄清/问题,我会通过自定义控件解决这个问题。我知道你拥有的是技术上的自定义控件,但我在谈论的是themes \ generic.xaml文件带来的那种:)。如果您不熟悉,我建议创建一个新的VS项目并使其成为“WPF自定义控件库”模板。然后,您应该能够添加模板“自定义控件(WPF)”的新类。您将看到VS为您生成了themes \ generic.xaml文件 - 您可以在此处为CustomTextBox保存controltemplate。我会get the default control template一个TextBox,并添加一个未被命中测试的TextBlock可见(因此用户可以点击进入你的可编辑区域)并在其上为HintText设置一个TemplateBinding。然后你就可以在任何地方重复使用这个自定义控件(因为它是在一个单独的dll中编译的......你也可以选择将它保存在你当前的项目中),获得你没有覆盖的文本框的默认行为,并且不会嵌套CustomTextBox。