捕获 ContentPresenter 中的内容更改





5.00/5 (11投票s)
本文介绍了一种捕获DependencyObject上PropertyChanged事件的方法,在本例中用于捕获ContentPresenter上的Content何时更改并设置焦点。
引言
我需要在一个TextBox
上设置初始焦点,但有一个问题。当包含TextBox
的UserControl
出现时,总有一个位于前景的UserControl
提供忙碌信息或错误情况。因此,在初始化或加载时设置焦点的常规方法不起作用。更糟糕的是,我将主窗口设计为使用ContentPresenters
,其Content
用于确定与Content
关联的ViewModel
所使用的DataTemplate
。
控件
用于捕获ContentPresenter
的Content
中更改的代码是通过创建一个新的、从ContentPresenter
派生的Control
来完成的。
public class ActionableContentPresenter : ContentPresenter
{
static ActionableContentPresenter()
{
ContentProperty.OverrideMetadata(typeof(ActionableContentPresenter),
new FrameworkPropertyMetadata(new PropertyChangedCallback(OnContentChanged)));
}
private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var mcc = d as ActionableContentPresenter;
mcc?.ContentChanged?.Invoke(mcc,
new DependencyPropertyChangedEventArgs(ContentProperty, e.OldValue, e.NewValue));
}
public event DependencyPropertyChangedEventHandler ContentChanged;
}
然后,在主窗口(或UserControl
)中,只需要将一个event
处理程序关联到此Control
的ContentChanged
event
。
public MainWindow()
{
InitializeComponent();
ActionableContentPresenter.ContentChanged += ActionableContentPresenter_ContentChanged;
}
在本文章的示例中,我只是检查ActionableContentPresenter
的Content
是否为null
,如果是,则可以设置焦点。
private void ActionableContentPresenter_ContentChanged(object sender,
DependencyPropertyChangedEventArgs e)
{
var mcc = sender as ActionableContentPresenter;
if (mcc.Content == null )
{
if (DisableSetFocus.IsChecked == false)
{
if (SetFocusTextBox2.IsChecked == false) TextBox1.Focus();
else TextBox2.Focus();
}
}
}
示例
该示例具有主要内容,其中包含许多控件,包括两个CheckBox
控件。其中一个CheckBox
控件将启用焦点设置,另一个会将焦点从第一个TextBox
更改为第二个TextBox
。 当单击“显示覆盖层”Button
时,将出现一个带有Panel
和一个“关闭”Button
的控件。 此Panel
将完全覆盖Window
中的其他控件,因此只能单击“关闭”Button
。 单击此Button
后,覆盖层Control
将消失。 如果选中“禁用焦点
”CheckBox
,则不会将焦点设置到窗体上的任何Control
。 但是,如果未选中IsChecked
,则焦点将出现在第一个或第二个TextBox
中,具体取决于是否选中“聚焦到文本框 2(否则为文本框 1)”CheckBox
的IsChecked
。
初始屏幕
单击“显示覆盖层”按钮后的屏幕
如果单击“显示备用内容”Button
,则带有TextBox
和Button
的Panel
将覆盖除Button
控件以外的所有控件。 如果单击“显示覆盖层”Button
,则会出现带有单个Button
的相同覆盖层Panel
,并且如果未选择“禁用焦点”CheckBox
,则焦点将位于TextBox
上。 否则,将没有焦点。
单击“显示备用内容”按钮后的屏幕
单击“显示备用内容”,然后单击“显示覆盖层”按钮后的屏幕
关注点
这种连接到现有DependencyProperties
的处理程序的能力应该被记住,因为它为执行非常规任务提供了很多选择。
我还考虑了如何将其变成一种行为,并计划研究该选项。
历史
- 2016 年 5 月 5 日:初始版本
- 2016 年 5 月 16 日:向文章和代码添加了
PriorityBinding
以进行比较 - 2016 年 5 月 21 日:更新了代码以包含
ContentPresentor
设置焦点示例