UWP - 在NavigationViewItems上设置IsEnabled

Ric*_*h S 6 c# uwp uwp-xaml

我有一个带NavigationView控件的UWP应用程序.通过MenuItemsSource在XAML中设置类型对象的集合来创建导航项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"
>
Run Code Online (Sandbox Code Playgroud)

我想绑定IsEnabled的属性NavigationViewItems是那些获得创建一个属性NavigationViewElement.我怎么能这样做?

我有一个类似的问题ListBox.在这种情况下,我能够从ListBox派生一个新类,它覆盖PrepareContainerForItemOverride()并设置基于绑定到的类中的数据的IsEnabled标志ListBoxItem(在本例中为OptionItem)

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);
}
Run Code Online (Sandbox Code Playgroud)

是否有一个等价的NavigationView?或是否有一些其他方式来表明应该绑定的IsEnabled标志?NavigationViewItemNavigationViewElement.IsItemEnabled

更新 我查看了Nico Zhu提出的解决方案,但我不确定如何将其应用于我的要求.这可能是由于我对XAML缺乏经验.

在我的实现中,由于我的布局要求,我从Selector对象引用的DataTemplates不包含NavigationViewItem元素.我不是简单地设置NavigationViewItem.Content和.Glyph,而是使用一堆控件填充Grid.这是一个示例:

<DataTemplate x:Key="MainPageNavigationViewItem1LineTemplate">
    <Grid Margin="{StaticResource MainPageNavigationViewItemTopGridMargin}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <FontIcon Glyph="{Binding Glyph, FallbackValue=&#xE14E;}" 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>
Run Code Online (Sandbox Code Playgroud)

结果如下所示,项目的内容设置与Grid的内容相同:

在此输入图像描述

这正是我需要的,但我无法弄清楚如何将项目的IsEnabled属性绑定到NavigationViewElement.IsItemEnabled.

当我尝试按照建议的模型时,将NavigationViewItem添加到DataTemplate,如下所示:

        <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>
Run Code Online (Sandbox Code Playgroud)

然后我可以根据需要绑定IsEnabled属性,但UI不能正确绘制.该项目的内容似乎在我已经拥有的那个上面添加了第二个NavigationViewItem.单击带有文本的区域不执行任何操作 - 我必须单击浅灰色区域外的项目才能进行导航.

在此输入图像描述

对我做错了什么的见解?总之,我希望找到一种方法来自定义NavigationViewItem的显示内容,同时还将IsEnabled属性绑定到模型中NavigationViewElement的属性.

Nic*_*SFT 5

与模型的绑定MenuItemsSource可以参考官方代码示例。在最新版本中,我们添加了有关设置数据源的新功能MenuItemsSource。如果你想启用或禁用NavigationViewItem,你可以IsEnabled在模型中创建属性然后绑定它。请检查以下代码。

\n\n

XAML代码

\n\n
<Page.Resources>\n    <local:MenuItemTemplateSelector x:Key="selector">\n        <local:MenuItemTemplateSelector.ItemTemplate>\n            <DataTemplate x:DataType="local:Category" >\n                <NavigationViewItem Content="{x:Bind Name}" \n                                    ToolTipService.ToolTip="{x:Bind Tooltip}" \n                                    IsEnabled="{x:Bind IsEnabled}" >\n                    <NavigationViewItem.Icon>\n                        <SymbolIcon Symbol="{x:Bind Glyph}" />\n                    </NavigationViewItem.Icon>\n                </NavigationViewItem>\n            </DataTemplate>\n        </local:MenuItemTemplateSelector.ItemTemplate >\n    </local:MenuItemTemplateSelector>\n</Page.Resources>\n<Grid>\n    <NavigationView x:Name="nvSample" \n            MenuItemTemplateSelector="{StaticResource selector}"                      \n            MenuItemsSource="{x:Bind Categories, Mode=OneWay}" />\n\n</Grid>\n
Run Code Online (Sandbox Code Playgroud)\n\n

代码隐藏

\n\n
public sealed partial class MainPage : Page\n{\n    public MainPage()\n    {\n        this.InitializeComponent();\n        Categories = new ObservableCollection<CategoryBase>();\n        Categories.Add(new Category { Name = "Category 1", Glyph = Symbol.Home, Tooltip = "This is category 1", IsEnabled = false });\n        Categories.Add(new Category { Name = "Category 2", Glyph = Symbol.Keyboard, Tooltip = "This is category 2", IsEnabled = true });\n        Categories.Add(new Category { Name = "Category 3", Glyph = Symbol.Library, Tooltip = "This is category 3" , IsEnabled = false });\n        Categories.Add(new Category { Name = "Category 4", Glyph = Symbol.Mail, Tooltip = "This is category 4", IsEnabled = true });\n    }\n\n    public ObservableCollection<CategoryBase> Categories { get;  set; }\n}\n\n\npublic class CategoryBase { }\n\npublic class Category : CategoryBase\n{\n    public string Name { get; set; }\n    public string Tooltip { get; set; }\n    public Symbol Glyph { get; set; }\n    public bool IsEnabled { get; set; }\n}\n\npublic class Separator : CategoryBase { }\n\npublic class Header : CategoryBase\n{\n    public string Name { get; set; }\n}\n\n[ContentProperty(Name = "ItemTemplate")]\nclass MenuItemTemplateSelector : DataTemplateSelector\n{\n    public DataTemplate ItemTemplate { get; set; }\n    protected override DataTemplate SelectTemplateCore(object item)\n    {\n        return item is Separator ? SeparatorTemplate : item is Header ? HeaderTemplate : ItemTemplate;\n    }\n    internal DataTemplate HeaderTemplate = (DataTemplate)XamlReader.Load(\n       @"<DataTemplate xmlns=\'http://schemas.microsoft.com/winfx/2006/xaml/presentation\'>\n               <NavigationViewItemHeader Content=\'{Binding Name}\' />\n              </DataTemplate>");\n\n    internal DataTemplate SeparatorTemplate = (DataTemplate)XamlReader.Load(\n        @"<DataTemplate xmlns=\'http://schemas.microsoft.com/winfx/2006/xaml/presentation\'>\n                <NavigationViewItemSeparator />\n              </DataTemplate>");\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在此输入图像描述

\n\n



\n\n

更新一

\n\n

问题的关键在于我们不能DataTemplate在1803中使用\xe2\x80\x99。一般来说,对于NavigationViewItem1803中的创建我们经常使用以下解决方案。

\n\n

沙姆尔

\n\n
<NavigationView x:Name="nvSample" MenuItemsSource="{x:Bind NavItems}" >\n\n</NavigationView>\n
Run Code Online (Sandbox Code Playgroud)\n\n

代码隐藏

\n\n
public ObservableCollection<Category> Categories { get; set; }\npublic MainPage()\n{\n    this.InitializeComponent();\n    Categories = new ObservableCollection<Category>();\n    Categories.Add(new Category { Name = "Category 1", Glyph = Symbol.Home, Tooltip = "This is category 1", IsEnabled = false });\n    Categories.Add(new Category { Name = "Category 2", Glyph = Symbol.Keyboard, Tooltip = "This is category 2", IsEnabled = true });\n    Categories.Add(new Category { Name = "Category 3", Glyph = Symbol.Library, Tooltip = "This is category 3", IsEnabled = true });\n    Categories.Add(new Category { Name = "Category 4", Glyph = Symbol.Mail, Tooltip = "This is category 4", IsEnabled = true });\n\n}\npublic IEnumerable<NavigationViewItemBase> NavItems\n{\n    get\n    {\n        return Categories.Select(\n               b => (new NavigationViewItem\n               {\n                   Content = b.Name,\n                   Icon = new SymbolIcon(b.Glyph),\n                   IsEnabled = b.IsEnabled,\n               })\n        );\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

简而言之,我们需要将数据模型转换为 NavigationViewItem. 但1803内不使用DataTemplate。请尝试这个。更详细的你也可以参考这个案例

\n