I am using the Hamburger Menu in a MVVM WPF application and have applied the Badge control to each menu item using a DataTemplate as follows: (taken from https://github.com/MahApps/MahApps.Metro/issues/3800).
`<DataTemplate x:Key="MenuItemTemplate" DataType="{x:Type Controls:HamburgerMenuIconItem}">
<Grid Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Controls:Badged Grid.Column="0"
Badge="{Binding DataContext.TestCount, RelativeSource={RelativeSource AncestorType=UserControl}}"
BadgeBackground="Red"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ContentControl Content="{Binding Icon}"
Margin="2"
Focusable="False"
IsTabStop="False" />
</Controls:Badged>
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
FontSize="16"
Text="{Binding Label}" />
</Grid>
</DataTemplate>`
This works fine, but this applies the same value to all menu items - in this example I am binding to a property named TestCount from MessagingMainViewModel (the view model for the view containing the markup for the HamburgerMenu control).
`<Controls:HamburgerMenu x:Name="HamburgerMenuControl"
HamburgerWidth="48"
IsPaneOpen="True"
CanResizeOpenPane="True"
ItemInvoked="HamburgerMenuControl_OnItemInvoked"
ItemTemplate="{StaticResource MenuItemTemplate}"
OptionsItemTemplate="{StaticResource MenuItemTemplate}"
SelectedIndex="0"
Style="{StaticResource MahApps.Styles.HamburgerMenu.Ripple}"
VerticalScrollBarOnLeftSide="False">
<!-- Items -->
<Controls:HamburgerMenu.ItemsSource>
<Controls:HamburgerMenuItemCollection>
<Controls:HamburgerMenuIconItem Icon="{iconPacks:FontAwesome Kind=CommentAltSolid}" Label="Chat">
<Controls:HamburgerMenuIconItem.Tag>
<views:ChatView />
</Controls:HamburgerMenuIconItem.Tag>
</Controls:HamburgerMenuIconItem>
<Controls:HamburgerMenuIconItem Icon="{iconPacks:FontAwesome Kind=PenSquareSolid}" Label="Compose">
<Controls:HamburgerMenuIconItem.Tag>
<views:ComposeMessageView />
</Controls:HamburgerMenuIconItem.Tag>
</Controls:HamburgerMenuIconItem>
<Controls:HamburgerMenuIconItem Icon="{iconPacks:Material Kind=InboxArrowDown}" Label="Inbox">
<Controls:HamburgerMenuIconItem.Tag>
<views:InboxView />
</Controls:HamburgerMenuIconItem.Tag>
</Controls:HamburgerMenuIconItem>
</Controls:HamburgerMenuItemCollection>
</Controls:HamburgerMenu.ItemsSource>
...`
Each of the menu items is a view, with it's own view model and I would like to bind to an exposed property from the ChatViewModel and InboxViewModel (but not the ComposeViewModel), for example, a property named UnreadCount. I do not have insances of the child view models in the MessagingMainViewModel (as there has been no need thus far in the application).
I know how to bind to a property on the MessagingMainViewModel (as the DataTemplate code above shows) but cannot find a way to access the "child" view's viewmodel - never mind use this in the DataTemplate somehow. Is this possible at all? Thanks.
You have your Content
set in the Tag
-Property. We can use this in our DataTemplate
to access anything in the Tag
-object. You say that your Tag is a UserControl
, so we can access its DataContext
.
Here is an example, assuming that the Property is the same for every view you have. If not, you need to use a TemplateSelector
:
<DataTemplate x:Key="MenuItemTemplate" DataType="{x:Type Controls:HamburgerMenuIconItem}">
<Grid Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Controls:Badged Grid.Column="0"
Badge="{Binding Tag.DataContext.[YourBadgePropertyGoesHere]}"
BadgeBackground="Red"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ContentControl Content="{Binding Icon}"
Margin="2"
Focusable="False"
IsTabStop="False" />
</Controls:Badged>
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
FontSize="16"
Text="{Binding Label}" />
</Grid>
</DataTemplate>