WPF UserControl检测LostFocus忽略儿童

Posted

技术标签:

【中文标题】WPF UserControl检测LostFocus忽略儿童【英文标题】:WPF UserControl detect LostFocus ignoring children 【发布时间】:2015-12-14 01:51:15 【问题描述】:

我有一个 UserControl 帽子,其中包含几个元素(列表框、按钮)和一个带有组合框和按钮的弹出窗口。

我尝试失去对用户控件的关注,但只要 UserControl 内的焦点发生变化,就会触发 Lost(Keyboard)Focus 事件。

但我不想知道一个孩子何时失去焦点到 UserControl 的另一个孩子,但我想知道,当键盘焦点移动到 UserControl 之外的元素时,它是 Popup。

有没有办法在不检查每个元素的 LostFocus 的情况下检测到这一点?

【问题讨论】:

你能分享一些代码吗?这样更容易纠正您所犯的任何错误或解决任何意外问题。也许你应该看看Control.Leave Event。 Control.Leave 是 Windows.Forms。 "如果您确实需要创建一个新的 WPF 控件,最简单的方法是创建一个派生自 UserControl (...) 的类,如果您愿意,从 UserControl 派生是一个合适的模型通过向其添加现有元素来构建您的控件,类似于构建应用程序的方式。(如果您想在控件中使用模板,请从 Control 派生。)" - 来源:MSDN UserControl Class 【参考方案1】:

此解决方案适合您吗?我在 UserControl 中创建了名为 LostFocusIgnoreChildren 的新事件,仅当新的焦点元素不是此 UserControl 的子元素时才会触发。

UserControl1.cs

  public partial class UserControl1 : UserControl
    
        public UserControl1()
        
            InitializeComponent();
        

        public event RoutedEventHandler LostFocusIgnoreChildren;
        private void UserControl_LostFocus(object sender, RoutedEventArgs e)
        
            var focused_element = FocusManager.GetFocusedElement(Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive));
            var parent = (focused_element as FrameworkElement).TryFindParent<UserControl1>();
            if (parent == null && LostFocusIgnoreChildren != null)
                LostFocusIgnoreChildren(this, e);
        
    

VisualTreeHelper 扩展

 public static class VisualTreeHelperExt
    
        public static T TryFindParent<T>(this DependencyObject child)
    where T : DependencyObject
        
            DependencyObject parentObject = GetParentObject(child);
            if (parentObject == null) return null;
            T parent = parentObject as T;
            if (parent != null)
            
                return parent;
            
            else
            
                return TryFindParent<T>(parentObject);
            
        

        public static DependencyObject GetParentObject(this DependencyObject child)
        
            if (child == null) return null;
            ContentElement contentElement = child as ContentElement;
            if (contentElement != null)
            
                DependencyObject parent = ContentOperations.GetParent(contentElement);
                if (parent != null) return parent;
                FrameworkContentElement fce = contentElement as FrameworkContentElement;
                return fce != null ? fce.Parent : null;
            
            FrameworkElement frameworkElement = child as FrameworkElement;
            if (frameworkElement != null)
            
                DependencyObject parent = frameworkElement.Parent;
                if (parent != null) return parent;
            
            return VisualTreeHelper.GetParent(child);
        
    

【讨论】:

另一种检查给定控件的焦点是否丢失以支持其(递归)子控件之一的方法是使用this code example。

以上是关于WPF UserControl检测LostFocus忽略儿童的主要内容,如果未能解决你的问题,请参考以下文章

WPF中UserControl控件的关闭

当我将WPF UserControl用于其内置项目以外的项目时,我的WPF UserControl无法找到资源

WPF 导航和销毁当前 UserControl

在WPF中UserControl

在 UserControl WPF MVVM caliburn 内的 UserControl 之间切换

数据绑定到 WPF 中的 UserControl