Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF UserControl detect LostFocus ignoring children

I have a UserControl hat contains several elements (ListBoxes, Buttons) and a Popup with ComboBoxes and Buttons.

I tried lost focus on the user contorl, but whenever the focus inside the UserControl changes, the Lost(Keyboard)Focus event fires.

But I don't want to know when a child loses focus to another child of the UserControl, but I want to know, when the keyboard focus moves to an element outside the UserControl and it's Popup.

Is there a way to detect that, without checking the LostFocus of every single element?

like image 663
bebo Avatar asked Sep 17 '15 08:09

bebo


1 Answers

Does this solution suit you? I've created new event, called LostFocusIgnoreChildren in the UserControl, which fires only if new focused element is not a child of this 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 extensions

 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);
        }
    }
like image 64
netaholic Avatar answered Nov 14 '22 04:11

netaholic