2015-09-17 57 views
3

我有一个UserControl帽子包含几个元素(ListBoxes,Buttons)和一个弹出框与组合框和按钮。WPF UserControl检测LostFocus忽略儿童

我试图在用户控制上失去焦点,但每当UserControl内部的焦点发生变化时,Lost(键盘)焦点事件就会触发。

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

有没有办法检测到,而不检查每个元素的LostFocus?

+0

能否请您分享一些代码?这样可以更轻松地纠正您正在制作的任何错误或解决任何意外问题。也许你应该看看[Control.Leave Event](https://msdn.microsoft.com/en-us/library/system.windows.forms.control.leave(v = vs.110).aspx) 。 – Oceans

+0

Control.Leave是Windows.Forms。 – bebo

+0

“如果你确实需要创建一个新的WPF控件,最简单的方法是创建一个从UserControl派生的类(...)如果你想通过向其添加现有元素来构建控件,从UserControl派生是一个合适的模型,类似于你如何构建一个应用程序(如果你想在你的控件中使用模板,可以从Control派生而来。)_“ - 源:[MSDN UserControl Class](https://msdn.microsoft.com/en-us /library/system.windows.controls.usercontrol(v=vs.110).aspx) – Oceans

回答

2

此解决方案是否适合您?我在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); 
     } 
    } 
+0

另一种检查给定控件的焦点是否因其递归的子控件而失去的方法可能是使用[this code示例](https://stackoverflow.com/a/14875652/997940)。 –