无法在 NavigationView MenuItemTemplate 中绑定图标 属性

Cannot bind Icon property in NavigationView MenuItemTemplate

我尝试使用 NavigationView,因为它看起来非常有用,但我正在努力使其与 MVVM 模式一起工作。

我已经附加了 MenuItemsSource 属性 就像这个片段:

<Page x:Class="App5.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:App5"
      ...>

    <Page.DataContext>
        <local:MainViewModel></local:MainViewModel>
    </Page.DataContext>

    <NavigationView MenuItemsSource="{Binding Items}">
        <NavigationView.MenuItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" />
            </DataTemplate>
        </NavigationView.MenuItemTemplate>
    </NavigationView>
</Page>

我得到的是这个:

这很酷,但是 NavigationViewItem 有一个 Icon 属性 可以用它装饰文本。

如何根据绑定的物品设置图标NavigationViewItem

注意: 我真的不想手动添加图标作为 MenuItemTemplate 的一部分,因为它不是应该的方式。我需要的是绑定隐式生成的 NavigationViewItems 的图标 属性。

问题是如何?

我试过这个(使用 MenuItemContainerStyle),但它不起作用:

<NavigationView MenuItemsSource="{Binding Items}">
    <NavigationView.MenuItemContainerStyle>
        <Style TargetType="NavigationViewItem">
            <Setter Property="Icon" Value="{Binding Converter={StaticResource ItemToIconConverter}}" />
        </Style>
    </NavigationView.MenuItemContainerStyle>
    <NavigationView.MenuItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
    </NavigationView.MenuItemTemplate>
</NavigationView>

注意: 使用下面答案中建议的 XAML(在 DataTemplate 中放置 NavigationViewItem),NavigationViewItem 在可视化树中重复(一个嵌套到另一个):

这不是解决方案。而且,它看起来和行为都很糟糕。查看建议解决方案的快照:

您声明您不想手动添加图标作为 MenuItemTemplate 的一部分,因为它不是人们认为的那样(这是绝对正确的) ,但您实际上为设置菜单项的文本做了完全相同的事情(手动添加 TextBlock 而不是设置菜单项的 Content 属性)。

TextBlock 覆盖任何自动创建的 NavigationItemView,因此没有要显示的图标元素(TextBlock 仅包含文本,没有图标)。

尝试简单地使用 NavigationViewItem 作为模板:

<NavigationView MenuItemsSource="{Binding Items}">
    <NavigationView.MenuItemTemplate>
        <DataTemplate>
            <NavigationViewItem Icon="{Binding Icon}" Content="{Binding Name}"/>
        </DataTemplate>
    </NavigationView.MenuItemTemplate>
</NavigationView>

这让我抓狂!可悲的是,似乎默认行为是 MenuItemTemplate 的内容放在 NavigationViewItemContentPresenter.

我解决这个问题的方法是复制 NavigationViewItem 默认样式的相关部分并稍微修改它:

<NavigationView.MenuItemTemplate>
    <DataTemplate>
        <Grid HorizontalAlignment="Left"
              Height="40"
              Margin="-16,0,0,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="48" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Viewbox Grid.Column="0"
                     Margin="16,12">
                <SymbolIcon Symbol="{x:Bind Icon}" />
            </Viewbox>
            <ContentPresenter Content="{x:Bind Name}"
                              Grid.Column="1"
                              VerticalAlignment="Center"/>
        </Grid>
    </DataTemplate>
</NavigationView.MenuItemTemplate>

修改包括为 Grid 设置负边距并添加两个 Grid.Column 属性。

我已经打开 an issue on the Docs GitHub 希望他们能更好地解释这种行为。