Anyone have any idea how to implement binding within the MenuItems?
You could set the ItemsSource of the HamburgerMenu to an IEnumerable and bind to a property of the type T in the ItemTemplate.
View:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
mc:Ignorable="d">
<Page.Resources>
<DataTemplate x:Name="ItemTemplate" x:DataType="local:Item">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<SymbolIcon Grid.Column="0" Symbol="{x:Bind Symbol}" />
<TextBlock Grid.Column="1" Text="{x:Bind Label, Mode=TwoWay}" VerticalAlignment="Center" />
</Grid>
</DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<controls:HamburgerMenu x:Name="hamburgerMenuControl"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
ItemTemplate="{StaticResource ItemTemplate}"
ItemClick="hamburgerMenuControl_ItemClick">
<ContentControl Content="{Binding SelectedItem.Content}" />
</controls:HamburgerMenu>
</Grid>
</Page>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.DataContext = new ViewModel();
}
private void hamburgerMenuControl_ItemClick(object sender, ItemClickEventArgs e)
{
//workaround to set the SelectedItem property of the view model when a new item is selected
(DataContext as ViewModel).SelectedItem = e.ClickedItem as Item;
}
}
View Model:
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
Items.Add(new Item() { Label = "1", Symbol = Symbol.Bullets, Content = "1..." });
Items.Add(new Item() { Label = "2", Symbol = Symbol.Bullets, Content = "2..." });
Items.Add(new Item() { Label = "3", Symbol = Symbol.Bullets, Content = "3..." });
SelectedItem = Items[0];
}
public IList<Item> Items { get; } = new List<Item>();
private Item _selectedItem;
public Item SelectedItem
{
get { return _selectedItem; }
set { _selectedItem = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Model:
public class Item : INotifyPropertyChanged
{
private string _label;
public string Label
{
get { return _label; }
set { _label = value; NotifyPropertyChanged(); }
}
public Symbol Symbol { get; set; }
public object Content { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Set the Label property of the model to the username or whatever you want to display in the options menu. This is how you data bind the HamburgerMenu using the recommended MVVM design pattern.
If you are defining the HamburgerMenuGlyphItems directly in the XAML markup of your view you could bind set up the binding programmatically in the code-behind of the same view:
<controls:HamburgerMenuGlyphItem x:Name="item" />
public MainPage()
{
this.InitializeComponent();
BindingOperations.SetBinding(item, HamburgerMenuGlyphItem.LabelProperty,
new Binding() { Path = new PropertyPath(nameof(Username)), Source = this });
}
public string Username { get; } = "username...";
}