动态焦点控制与内容呈现器的交互

在WPF应用程序开发中,经常会遇到需要动态设置控件焦点的场景。例如,当一个包含TextBox的UserControl出现时,如果有一个前景UserControl正在显示忙碌信息或者错误状态,那么常规的初始化或加载时设置焦点的方法就无法工作。为了解决这个问题,可以通过自定义控件和事件处理来实现动态焦点控制。

首先,定义了一个名为ActionableContentPresenter的自定义控件,它继承自ContentPresenter。通过重写ContentProperty的元数据,可以在Content发生变化时触发一个事件。这样,就可以在主窗口或UserControl中为这个事件绑定一个事件处理程序。

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; }

在主窗口的构造函数中,为ActionableContentPresenter的ContentChanged事件绑定了一个事件处理程序。在这个事件处理程序中,检查ActionableContentPresenter的Content是否为null。如果是,并且DisableSetFocus选项没有被选中,那么就可以根据SetFocusTextBox2选项的值来决定焦点应该设置在第一个还是第二个TextBox上。

public MainWindow() { InitializeComponent(); ActionableContentPresenter.ContentChanged += ActionableContentPresenter_ContentChanged; } 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。当点击"Show Overlay"按钮时,会出现一个带有单个"Close"按钮的Panel,这个Panel会完全覆盖其他控件,使得只能点击"Close"按钮。当点击这个按钮时,覆盖的控件会消失。如果选中了"Disable Focus"CheckBox,那么表单上不会有任何控件获得焦点。如果没有选中,那么焦点会出现在第一个或第二个TextBox上,这取决于"Focus on TextBox 2 (otherwise TextBox 1)"CheckBox是否被选中。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485