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