WPF网格及其内部控件的焦点

本文关键字:控件 焦点 内部 网格 WPF | 更新日期: 2023-09-27 18:28:26

我有MyContainer内部带有网格的用户控件。此网格的每个单元格都包含一个派生自MyControlBase类的some控件。这些控件是动态添加的。

我需要在MyContainer中实现FocusedControl绑定属性,以获得当前焦点或将焦点设置为MySontrolBase的任何子级。我知道FocusManager.FocusedElement,但不知道如何正确实现它。

WPF网格及其内部控件的焦点

不知道这是否有助于您的情况,或者这是否是处理我的情况的正确方法,但在紧要关头,我发现在我想要关注的对象上侦听Loaded事件,然后使用Dispatcher.BeginInvoke在后台或ApplicationIdle优先级上向我的控件发送focus请求,在其他方法没有的情况下是有效的。例如:

private void MyControlLoaded(object sender, RoutedEventArgs e)
{
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action( () => MyControl.Focus() ));
}

好吧,我自己找到了方法。

首先像往常一样定义我们的新依赖性属性FocusedAdapterProperty

    public static readonly DependencyProperty FocusedAdapterProperty;
    static SpreadGridControl()
    {
        FocusedAdapterProperty = DependencyProperty.Register("FocusedAdapter",
                            typeof(object), typeof(SpreadGridControl),
                            new FrameworkPropertyMetadata(null, null));
    }
    public object FocusedAdapter
    {
        get { return GetValue(FocusedAdapterProperty); }
        set { SetValue(FocusedAdapterProperty, value); }
    }

接下来,将GotFocus处理程序添加到父容器中,例如<Grid GotFocus="Grid_OnGotFocus">
检查e.OriginalSource并搜索所需类型的最常见祖先,并将属性设置为新值:

    private void Grid_OnGotFocus(object sender, RoutedEventArgs e)
    {
        var control = UIHelpers.TryFindParent<ControlBase>
            ((DependencyObject)e.OriginalSource);
        if (control != null)
            FocusedAdapter = control.Adapter;
    }

TryFindParent的实现可以在这里找到