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

MenuItems cannot be activated via keyboard #84

Closed lukasf closed 11 years ago

lukasf commented 12 years ago

As the title says, currently it is not possible to use the menu with the keyboard. I see two possibilities to solve this. Either attach Key events to the menu items. Or change MenuItemBase to inherit from Button. Then Commmand and Click would come for free, both are automatically called on mouse/tab/key events. Not sure if that would be a good idea, but it is at least an option.

I will probably do some experiments on my own and let you know. But perhaps you already have an idea how you want to do this?

timheuer commented 12 years ago

Yes I've had this issue for a while, if you see MenuItem, line 88 you'll see that I look for Enter/Space and call OnTapped, but it isn't working. Any suggestions/help you can provide is awesome. Another set of eyes is always good. I have thought about moving to Button but just never have. At this point moving to Button might have adverse side effects and I'd rather not since people are using it and that is more of a fundamental change.

stefanolson commented 11 years ago

Tim,

Not sure you are going to like my solution, but, here it is anyway: so in MenuItem.OnKeyDown, I have added these lines: // Issue #84: https://github.com/timheuer/callisto/issues/84 // looks like calling base.OnTapped doesn't actually call the tapped // handler, so let's call it directly. Menu menu = TryFindVisualTreeParent

(this); if (menu == null) return; menu.OnMenuItemSelected(this, null);

And then the function to get the parent: ///

/// Finds a parent of a given item on the visual tree. ///

/// The type of the queried item. /// A direct or indirect child of the /// queried item. /// The first parent item that matches the submitted /// type parameter. If notmatching item can be found, a null /// reference is being returned. public static T TryFindVisualTreeParent(DependencyObject child) where T : DependencyObject { if (child == null) return null; //get parent item DependencyObject parentObject = VisualTreeHelper.GetParent(child);

//we’ve reached the end of the tree
if (parentObject == null)
{

if NETFX_CORE

    // can return null even if there is a parent:  http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/01818109-0886-4c80-999b-94d11608eef4
    if (child is FrameworkElement)
    {
        parentObject = (child as FrameworkElement).Parent;
    }
    if (parentObject == null) return null;

else

    return null;

endif

}
//check if the parent matches the type we’re looking for
T parent = parentObject as T;
return parent ?? TryFindVisualTreeParent<T>(parentObject);

}

And in Menu, made OnMenuItemSelected internal.

Seems to work for me! :-)