I'm not too sure if this is the best place to ask this but I thought I'd give it a go.
I'm trying to implement a Hamburger Menu into my application using MahApps Metro UI Toolkit which worked great in a test window I made. So I then started moving to one of my main windows which makes use of a View Model.
The problem is, any bindings within the HamburgerMenu do not work at all, but works fine outside of the HamburgerMenu control.
[Example View:
This picture shows the test window mockup I made to show an example. The title and both textboxes are all bound to "MyTitle". As you can see, the one within the HamburgerMenu does not work.
I have tried binding the ViewModel to the HamburgerMenu control as well which did not work. I'd imagine it would have to be bound to "TheContentGrid" or "TheContent" controls within the HamburgerMenu ControlTemplate but those are not accessible from the Code Behind.
XAML:
<Controls:MetroWindow
..
Title="{Binding MyTitle}"
..>
<Grid>
<Grid.Resources>
<DataTemplate x:Key="MenuItemTemplate" DataType="{x:Type Controls:HamburgerMenuGlyphItem}">
<Grid Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Segoe MDL2 Assets" Text="{Binding Glyph}" />
<TextBlock Grid.Column="1" VerticalAlignment="Center" FontSize="16" Text="{Binding Label}" />
</Grid>
</DataTemplate>
</Grid.Resources>
<TextBox Text="{Binding MyTitle}" HorizontalAlignment="Right" />
<Controls:HamburgerMenu Margin="0 30 0 0"
SelectedIndex="0"
x:Name="HamburgerMenuControl"
ItemTemplate="{StaticResource MenuItemTemplate}"
OptionsItemTemplate="{StaticResource MenuItemTemplate}"
ItemClick="HamburgerMenuControl_OnItemClick"
OptionsItemClick="HamburgerMenuControl_OnItemClick"
DisplayMode="CompactOverlay">
<!-- Items -->
<Controls:HamburgerMenu.ItemsSource>
<Controls:HamburgerMenuItemCollection>
<Controls:HamburgerMenuGlyphItem Glyph="" Label="Home">
<Controls:HamburgerMenuGlyphItem.Tag>
<Grid>
<TextBox Text="{Binding MyTitle}" HorizontalAlignment="Center" VerticalAlignment="Top"/>
<TextBlock Text="Home View" FontSize="32" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Controls:HamburgerMenuGlyphItem.Tag>
</Controls:HamburgerMenuGlyphItem>
</Controls:HamburgerMenuItemCollection>
</Controls:HamburgerMenu.ItemsSource>
<!-- Content -->
<Controls:HamburgerMenu.ContentTemplate>
<DataTemplate DataType="{x:Type Controls:HamburgerMenuItem}">
<Grid x:Name="TheContentGrid">
<ContentControl x:Name="TheContent" Content="{Binding Tag}" />
</Grid>
</DataTemplate>
</Controls:HamburgerMenu.ContentTemplate>
</Controls:HamburgerMenu>
</Grid>
</Controls:MetroWindow>
Code Behind & View Model
public partial class WindowTest : MetroWindow
{
public WindowTest()
{
InitializeComponent();
DataContext = new TestViewModel();
}
private void HamburgerMenuControl_OnItemClick(object sender, ItemClickEventArgs e)
{
HamburgerMenuControl.Content = e.ClickedItem;
HamburgerMenuControl.IsPaneOpen = false;
}
}
public class TestViewModel : BindableBase
{
private string myTitle;
public string MyTitle
{
get { return myTitle; }
set { SetProperty(ref myTitle, value); }
}
public TestViewModel()
{
MyTitle = "Title from VM";
}
}
Please let me know if more information is required.
Maybe my answer comes a bit late for you but may help others. I just stumbled across this issue myself and could resolve it using the solution described in this answer.
Because HamburgerMenuGlyphItem
will not be part of the visual or logical tree, there is no binding ancestor for the DataContext
. i.e. your binding has no source to bind to.
Create an instance of a helper object in the resources and set the source of the binding explicitly to it using StaticResource
:
<Controls:MetroWindow.Resources>
<local:BindingProxy x:Key="Proxy" Data="{Binding}" />
</Controls:MetroWindow.Resources>
...
<Controls:HamburgerMenuGlyphItem.Tag>
<Grid>
<TextBox Text="{Binding Data.MyTitle, Source={StaticResource Proxy}}" />
</Grid>
</Controls:HamburgerMenuGlyphItem.Tag>
Here is the code for the helper object (source):
public class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}