7
votes

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?

1
Could you please share some code? This way it's easier to correct any mistakes you're making or solve any unexpected problems. Perhaps you should take a look at the Control.Leave Event.Oceans
Control.Leave is Windows.Forms.bebo
"If you do need to create a new WPF control, the simplest way is to create a class that derives from UserControl (...) deriving from UserControl is a suitable model if you want to build your control by adding existing elements to it, similar to how you build an application. (If you want to use templates with your control, derive from Control instead.)" - Source: MSDN UserControl ClassOceans

1 Answers

5
votes

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);
        }
    }