timheuer / callisto

A control toolkit for Windows 8 XAML applications. Contains some UI controls to make it easier to create Windows UI style apps for the Windows Store in accordance with Windows UI guidelines.
http://timheuer.com/blog/archive/2012/05/31/introducing-callisto-a-xaml-toolkit-for-metro-apps.aspx
Other
338 stars 108 forks source link

Menu focus issues #83

Closed lukasf closed 12 years ago

lukasf commented 12 years ago

There are some issues with menu focus handling.

  1. If the pointer enters a menu item, it gets activated. If you now move the pointer out of the menu, it gets deactivated. Now if you re-enter the same menu item (without hovering over a different item), it does not get activated.

Reason is that _isActive is only set on GotFocus, but the menu item stays focused all the time. Fixed by adding the following code in both OnPointerEntered and OnPointerMoved:

        _isActive = true;
        UpdateState(true);
  1. If the menu is placed in a popup, it initially is not focused. Keyboard navigation does not work properly ontil you once move the mouse into the menu.

Fix #1: Focus the content of a flyout once it is opened, at very end of OnHostPopupOpened:

        var content = Content as Control;
        if (content != null)
        {
            content.Focus(Windows.UI.Xaml.FocusState.Programmatic);
        }

Fix #2: Change focus handling code in Menu:

    private void ChangeFocusedItem(bool ascendIndex)
    {
        var focusedElement = FocusManager.GetFocusedElement();
        int startIndex;

        if ((focusedElement == _itemContainerList || focusedElement == this) && _items.Count > 0)
        {
            // focused item is the menu or the item container list, so try to set focus to an initial item
            startIndex = GetNextItemIndex(-1, ascendIndex);
        }
        else if (focusedElement is MenuItem && _items.Contains((MenuItem)focusedElement))
        {
            // focused item is already one of our menu items, so try to set focus to next
            startIndex = GetNextItemIndex(_items.IndexOf((MenuItem)focusedElement), ascendIndex);
        }
        else
        {
            // focus is outside of the menu
            return;
        }