I have a UWP app with a NavigationView
control. The navigation items are created by setting MenuItemsSource
in the XAML to a collection of objects of type NavigationViewElement
.
<NavigationView
Style="{StaticResource MainPageNavControlStyle}"
HeaderTemplate="{StaticResource MainPageNavHeaderTemplate}"
MenuItemsSource="{Binding NavigationViewElements}"
MenuItemContainerStyleSelector="{StaticResource NavStyleSelector}"
MenuItemTemplateSelector="{StaticResource NavItemTemplateSelector}"
x:Name="NavigationViewControl"
CompactModeThresholdWidth="480"
ExpandedModeThresholdWidth="635"
OpenPaneLength="324"
Loaded="OnControlLoaded"
ItemInvoked="OnItemInvoked"
IsTabStop="False"
IsSettingsVisible="False"
>
I would like to bind the IsEnabled
property of the NavigationViewItems
that get created to a property on NavigationViewElement
. How might I do that?
I had a similar question for a ListBox
. In that case, I was able to derive a new class from ListBox that overrides PrepareContainerForItemOverride()
and sets the IsEnabled
flag of the ListBoxItem
based on the data in the class to which it is bound (OptionItem, in this case)
protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
{
ListBoxItem lItem = element as ListBoxItem;
OptionItem oItem = item as OptionItem;
if (lItem != null && oItem != null)
{
lItem.IsEnabled = oItem.IsEnabled;
}
base.PrepareContainerForItemOverride(element, item);
}
Is there an equivalent for NavigationView?
Or is there some other way to indicate that the IsEnabled
flag for the NavigationViewItem
should be bound to NavigationViewElement.IsItemEnabled
?
Update I looked at the solution proposed by Nico Zhu but I am not sure how to apply it to my requirements. That could be due to my inexperience with XAML.
In my implementation, the DataTemplates that I reference from my Selector object do not include a NavigationViewItem element, due to my layout requirements. Rather than simply setting NavigationViewItem.Content and .Glyph, I populate a Grid with a bunch of controls. Here is a sample:
<DataTemplate x:Key="MainPageNavigationViewItem1LineTemplate">
<Grid Margin="{StaticResource MainPageNavigationViewItemTopGridMargin}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<FontIcon Glyph="{Binding Glyph, FallbackValue=}" FontFamily="{Binding FontFamily, FallbackValue=xGlyph}" FontSize="{StaticResource MainPageNavigationViewItemGlyphFontSize}" VerticalAlignment="Center" Margin="{StaticResource MainPageNavigationViewItemGlyphMargin}"/>
<StackPanel Grid.Column="1" Margin="{StaticResource MainPageNavigationViewItemTextMargin}" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<TextBlock x:Name="Header"
Text="{Binding TheSummaryHelper.SummaryHeaderLabel, FallbackValue=TheHeader}"
Style="{StaticResource DefaultFontStyle}"
/>
<TextBlock x:Name="Line1"
Text="{Binding TheSummaryHelper.Line1.DisplayString, FallbackValue=TheFirstLine}"
Visibility="{Binding TheSummaryHelper.Line1.ItemVisibility, FallbackValue=Visible}"
Style="{StaticResource SmallSummaryTextStyle}"
/>
</StackPanel>
</Grid>
</DataTemplate>
The result looks like this, with the item's contents set equal to those of the Grid:
It's exactly what I need, but I couldn't figure out how to bind the IsEnabled property of the item to NavigationViewElement.IsItemEnabled.
When I tried to follow the model suggested, adding a NavigationViewItem to the DataTemplate like this:
<misc:MainPageNavigationViewItemTemplateSelector
x:Key="NavItemTemplateSelector"
>
<misc:MainPageNavigationViewItemTemplateSelector.ItemTemplate>
<DataTemplate x:DataType="vm_misc:NavigationViewElement">
<NavigationViewItem IsEnabled="{x:Bind IsItemEnabled}" Content="{x:Bind TheSummaryHelper.SummaryHeaderLabel}">
</NavigationViewItem>
</DataTemplate>
</misc:MainPageNavigationViewItemTemplateSelector.ItemTemplate>
</misc:MainPageNavigationViewItemTemplateSelector>
then I am able to bind the IsEnabled property as desired, but the UI does not draw properly. The Content for the item seems to add a second NavigationViewItem on top of the one I already had. Clicking the area with the text does nothing - I have to click on the item outside the light gray area to cause navigation to occur.
Any insights into what I'm doing wrong? In summary, I am hoping to find a way to both customize the display contents of the NavigationViewItem while also binding the IsEnabled property to a property on the NavigationViewElement in my model.