Skip to content

Instantly share code, notes, and snippets.

@voidtuxic
Created November 25, 2015 16:44
Show Gist options
  • Save voidtuxic/9fe514ab7eaf590ba1a8 to your computer and use it in GitHub Desktop.
Save voidtuxic/9fe514ab7eaf590ba1a8 to your computer and use it in GitHub Desktop.
MVVM, UWP and MenuFlyout binding
<!-- helper is the namespace with your converter -->
<helper:MenuItemToMenuFlyoutConverter x:Key="menuToFlyout"/>
<!-- button is simply binded to a MenuItem instance -->
<Button x:Name="menuItem" FlyoutBase.AttachedFlyout="{Binding Converter={StaticResource menuToFlyout}}"
Click="menuItem_Click" Content="{Binding Title}"/>
// code behind
private void menuItem_Click(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
var item = btn.DataContext as MenuItem;
if(item.HasChildren)
{
FlyoutBase.ShowAttachedFlyout(btn);
}
else
{
item.Command.Execute(null);
}
}
// Using MVVM light, replace ViewModelBase with your MVVM framework
public class MenuItem : ViewModelBase
{
private readonly List<MenuItem> _items = new List<MenuItem>();
private readonly string _title;
private RelayCommand _command;
public MenuItem(string title)
: this(title, new RelayCommand(()=> { }, () => { return false; }))
{ }
public MenuItem(string title, RelayCommand command)
{
_title = title;
_icon = icon;
_command = command;
}
private MenuItem()
{
IsSeparator = true;
}
public bool IsSeparator { get; private set; }
public List<MenuItem> Items
{
get
{
return _items;
}
}
public bool HasChildren { get { return _items.Count > 0; } }
public string Title { get { return _title; } }
public RelayCommand Command { get { return _command; } }
}
public class MenuItemToMenuFlyoutConverter : IValueConverter
{
// this does not include sublevel menus right now
public object Convert(object value, Type targetType, object parameter, string language)
{
var item = value as MenuItem;
MenuFlyout menuFlyout = null;
if (item.HasChildren)
{
menuFlyout = new MenuFlyout();
menuFlyout.Opening += (object sender, object e) =>
{
// if needed, check if your commands are available
MenuFlyout flyout = sender as MenuFlyout;
foreach (MenuFlyoutItem it in flyout.Items.Where(i => i is MenuFlyoutItem))
{
(it.Command as RelayCommand).RaiseCanExecuteChanged();
}
};
foreach (var subItem in item.Items)
{
MenuFlyoutItemBase flyoutItem;
if (subItem.IsSeparator)
{
flyoutItem = new MenuFlyoutSeparator();
}
else
{
// if you have sublevel menus, you could call the converter for recursive menu creation here
menuFlyout.Placement = FlyoutPlacementMode.Bottom;
var menuFlyoutItem = new MenuFlyoutItem
{
Text = subItem.Title,
Command = subItem.Command
};
flyoutItem = menuFlyoutItem;
}
menuFlyout.Items.Add(flyoutItem);
}
}
return menuFlyout;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException(); // we don't really care about going back
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment