2015-09-17 65 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)。 –