Strange focus behavior for simple WPF ItemsControl

后端 未结 2 1345
别那么骄傲
别那么骄傲 2021-02-10 07:22

I\'m seeing strange behavior when it comes to focus and keyboard navigation. In the example below I have a simple ItemsControl that has been templated so that it presents a list

2条回答
  •  野的像风
    2021-02-10 07:35

    @Meleak explained the problem very well. Please read the article http://www.codeproject.com/KB/WPF/EnhancedFocusScope.aspx to fully understand what the problem is and how to solve it. I will just add the complete implementation of IsEnhancedFocusScope attached behavior mentioned in the article:

    public static class FocusExtensions
    {
        private static bool SettingKeyboardFocus { get; set; }
    
        public static bool GetIsEnhancedFocusScope(DependencyObject element) {
            return (bool)element.GetValue(IsEnhancedFocusScopeProperty);
        }
    
        public static void SetIsEnhancedFocusScope(DependencyObject element, bool value) {
            element.SetValue(IsEnhancedFocusScopeProperty, value);
        }
    
        public static readonly DependencyProperty IsEnhancedFocusScopeProperty =
            DependencyProperty.RegisterAttached(
                "IsEnhancedFocusScope",
                typeof(bool),
                typeof(FocusExtensions),
                new UIPropertyMetadata(false, OnIsEnhancedFocusScopeChanged));
    
        private static void OnIsEnhancedFocusScopeChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e) {
            var item = depObj as UIElement;
            if (item == null)
                return;
    
            if ((bool)e.NewValue) {
                FocusManager.SetIsFocusScope(item, true);
                item.GotKeyboardFocus += OnGotKeyboardFocus;
            }
            else {
                FocusManager.SetIsFocusScope(item, false);
                item.GotKeyboardFocus -= OnGotKeyboardFocus;
            }
        }
    
        private static void OnGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
            if (SettingKeyboardFocus) {
                return;
            }
    
            var focusedElement = e.NewFocus as Visual;
    
            for (var d = focusedElement; d != null; d = VisualTreeHelper.GetParent(d) as Visual) {
                if (FocusManager.GetIsFocusScope(d)) {
                    SettingKeyboardFocus = true;
    
                    try {
                        d.SetValue(FocusManager.FocusedElementProperty, focusedElement);
                    }
                    finally {
                        SettingKeyboardFocus = false;
                    }
    
                    if (!(bool)d.GetValue(IsEnhancedFocusScopeProperty)) {
                        break;
                    }
                }
            }
        }
    }
    

    In your XAML you just need to set this attached property instead of standard IsFocusScope property:

    
        
            
                
            
        
    
    

    It will work as you expect the focus scope to work.

提交回复
热议问题