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

PlacementTarget: gridview places contextmenu at top of page #60

Closed BucolicGeek closed 12 years ago

BucolicGeek commented 12 years ago

Question: what should the PlacementTarget be when using a GridView? I'm showing a context menu in response to a GridView_SelectionChanged event. Specifying the "sender" as the PlacementTarget puts the context menu at the top of the page -- regardless of the PlacementMode choice. And, specifying PlamentMode "Mouse" causes an exception. Suggestions? Rick

timheuer commented 12 years ago

Can you provide a repro please? If you are truly using a context menu (ie. a right click) you should use the Context menu classes in WinRT

BucolicGeek commented 12 years ago

It is pretty easy to reproduce. I'm not really needing a true context menu. Start a new VS project. Make a c# gridview app. Edit the GroupedItemsPage.XAML. On the GridView control, change selectionmode to single and add an event handler for SelectionChanged. In the selection-changed event handler, basically add your ShowFlyoutMenu method from the Callisto sample app. When running the app, select an item and the flyout menu appears at the top/center of the screen. If you change the placement to "mouse" an exception is thrown.

timheuer commented 12 years ago

Mouse is not support as placement (per the exception). The PlacementTarget in this case is the GridView and not the element so that is why you see this.

As you are describing this it is expected. Given your scenario you'd have to find the actual UIElement being clicked on and set that as the target

-th

Sent from mobile - please excuse tone and brevity

On Jul 21, 2012, at 7:10 AM, BucolicGeekreply@reply.github.com wrote:

It is pretty easy to reproduce. I'm not really needing a true context menu. Start a new VS project. Make a c# gridview app. Edit the GroupedItemsPage.XAML. On the GridView control, change selectionmode to single and add an event handler for SelectionChanged. In the selection-changed event handler, basically add your ShowFlyoutMenu method from the Callisto sample app. When running the app, select an item and the flyout menu appears at the top/center of the screen. If you change the placement to "mouse" an exception is thrown.


Reply to this email directly or view it on GitHub: https://github.com/timheuer/callisto/issues/60#issuecomment-7153194

BucolicGeek commented 12 years ago

I found a way to get the flyout to appear near the selected gridview item. First, in the XAML, I bind a unique key to the "Tag" of a UI Element. I choose a Grid element that contains each item. Then in the "OnGridSelectionChanged" event handler I search the visual-tree for that tag with this method call: Grid gridElement = FindVisualChildTag(TopGridViewElement, searchKey);

Here is the method I call to search for the selected grid element -- in case anyone else has a similar need.

private childItem FindVisualChildTag(DependencyObject obj, int pinnumber) where childItem : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child != null && child is childItem) { FrameworkElement element = (FrameworkElement)child; //Helper.LogMessage("found tag:" + element.Tag); int tagid = 0; try { if (element.Tag!=null) tagid = int.Parse(element.Tag.ToString()); } catch { tagid = 0; } if (tagid == pinnumber) return (childItem)child; } if (child != null) { childItem childOfChild = FindVisualChildTag(child, pinnumber); if (childOfChild != null) return childOfChild; } } return null; }