UWP - 具有两个不同来源的 NavigationView

UWP - NavigationView with two different Sources

我有一个 ObservableCollection<Category> 绑定到 NavigationView,其中 Category 是实现 INotifyPropertyChanged 的自定义 class。我创建了一个 DataTemplate 来显示集合的元素

<DataTemplate x:Key="CategoryTemplate">
    <NavigationViewItem  Icon="{Binding Icon}" RightTapped="CategoryItem_RightTapped">
        <local:CategoryViewItem CategoryItem="{Binding Mode=TwoWay}"/>
    </NavigationViewItem>
</DataTemplate>

现在我想在列表的顶部添加一些默认的 NavigationViewItemNavigationViewItemSeparator,而另一个 DataTemplate 保留第二部分 "Observable" 和 "Notifying changes of properties"。您可以在下图中看到我的意思的示例。

根据您的要求,您需要为 NavigationView 创建 MenuItemTemplateSelector。并根据数据源传递不同的DataTemplate

默认 NavigationViewItem 和 NavigationViewItemSeparator 数据模型

public class CategoryBase { }

public class DefaultCategory: CategoryBase
{
    public string Name { get; set; }
    public string Tooltip { get; set; }
    public Symbol Glyph { get; set; }
}
public class CustomCategory : CategoryBase
{
    public SymbolIcon Icon { get; set; }
    public string Title { get; set; }
}

public class Separator : CategoryBase { }

MenuItemTemplateSelector

public class MenuItemTemplateSelector : DataTemplateSelector
{
    internal DataTemplate SeparatorTemplate = (DataTemplate)XamlReader.Load(
        @"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
                <NavigationViewItemSeparator />
              </DataTemplate>");
    public DataTemplate DefaultItemTemlate { get; set; }
    public DataTemplate CustomItemTemlate { get; set; }
    protected override DataTemplate SelectTemplateCore(object item)
    {
        return item is Separator ? SeparatorTemplate : item is CustomCategory ? CustomItemTemlate : DefaultItemTemlate;
    }
}

Xaml代码

<Page.Resources>
    <local:MenuItemTemplateSelector x:Key="selector">
        <local:MenuItemTemplateSelector.DefaultItemTemlate>
            <DataTemplate x:DataType="local:DefaultCategory">
                <NavigationViewItem Content="{x:Bind Name}">
                    <NavigationViewItem.Icon>
                        <SymbolIcon Symbol="{x:Bind Glyph}" />
                    </NavigationViewItem.Icon>
                </NavigationViewItem>
            </DataTemplate>
        </local:MenuItemTemplateSelector.DefaultItemTemlate>
        <local:MenuItemTemplateSelector.CustomItemTemlate>
            <DataTemplate>
                <NavigationViewItem Icon="{Binding Icon}">
                    <TextBlock Text="{Binding Title}" />
                </NavigationViewItem>
            </DataTemplate>
        </local:MenuItemTemplateSelector.CustomItemTemlate>
    </local:MenuItemTemplateSelector>
</Page.Resources>
<Grid>
    <NavigationView
        x:Name="nvSample"
        MenuItemTemplateSelector="{StaticResource selector}"
        MenuItemsSource="{x:Bind Categories, Mode=OneWay}"
        />
    <Button Click="Button_Click" Content="AddItem" />
</Grid>

用法

public MainPage()
{
    this.InitializeComponent();
    Categories = new ObservableCollection<CategoryBase>();
    Categories.Add(new CustomCategory { Title = "This is Titlte", Icon = new SymbolIcon(Symbol.Play) });
}
public ObservableCollection<CategoryBase> Categories { get; }

private void Button_Click(object sender, RoutedEventArgs e)
{
    Categories.Insert(0, new Separator());
    Categories.Insert(0, new DefaultCategory { Name = "Category 1", Glyph = Symbol.Home, Tooltip = "This is category 1" });

}

您可以找到您可以参考的code sample here, and this NavigationView document