我有一个带有NavigationView控件的UWP应用。通过将XAML中的MenuItemsSource设置为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"
>

我想将创建的IsEnabledNavigationViewItems属性绑定(bind)到NavigationViewElement上的属性。我该怎么办?

我对ListBox也有类似的问题。在这种情况下,我能够从ListBox派生一个新类,该类重写PrepareContainerForItemOverride()并根据绑定(bind)到其的类中的数据设置IsEnabledListBoxItem标志(在这种情况下为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);
}

是否有NavigationView?的等效项?是否有其他方法表明IsEnabledNavigationViewItem标志应绑定(bind)到NavigationViewElement.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>

结果看起来像这样,项目的内容设置为等于Grid的内容:

c# - UWP-在NavigationViewItems上设置IsEnabled-LMLPHP

正是我所需要的,但是我不知道如何将项目的IsEnabled属性绑定(bind)到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>

那么我就可以根据需要绑定(bind)IsEnabled属性,但是UI无法正确绘制。该项目的内容似乎在我已经拥有的项目之上添加了第二个NavigationViewItem。单击带有文本的区域无济于事-我必须单击浅灰色区域之外的项目才能进行导航。

c# - UWP-在NavigationViewItems上设置IsEnabled-LMLPHP

对我在做什么错有任何见解吗?总之,我希望找到一种既可以自定义NavigationViewItem的显示内容,又可以将IsEnabled属性绑定(bind)到模型中NavigationViewElement上的属性的方法。

最佳答案

为了将MenuItemsSource与模型绑定(bind),可以引用official code sample。在最新版本中,我们添加了有关为MenuItemsSource设置数据源的新功能。如果要启用或禁用NavigationViewItem,可以在模型中创建IsEnabled属性,然后将其绑定(bind)。请检查以下代码。

Xaml代码

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

</Grid>

后面的代码
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        Categories = new ObservableCollection<CategoryBase>();
        Categories.Add(new Category { Name = "Category 1", Glyph = Symbol.Home, Tooltip = "This is category 1", IsEnabled = false });
        Categories.Add(new Category { Name = "Category 2", Glyph = Symbol.Keyboard, Tooltip = "This is category 2", IsEnabled = true });
        Categories.Add(new Category { Name = "Category 3", Glyph = Symbol.Library, Tooltip = "This is category 3" , IsEnabled = false });
        Categories.Add(new Category { Name = "Category 4", Glyph = Symbol.Mail, Tooltip = "This is category 4", IsEnabled = true });
    }

    public ObservableCollection<CategoryBase> Categories { get;  set; }
}


public class CategoryBase { }

public class Category : CategoryBase
{
    public string Name { get; set; }
    public string Tooltip { get; set; }
    public Symbol Glyph { get; set; }
    public bool IsEnabled { get; set; }
}

public class Separator : CategoryBase { }

public class Header : CategoryBase
{
    public string Name { get; set; }
}

[ContentProperty(Name = "ItemTemplate")]
class MenuItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate ItemTemplate { get; set; }
    protected override DataTemplate SelectTemplateCore(object item)
    {
        return item is Separator ? SeparatorTemplate : item is Header ? HeaderTemplate : ItemTemplate;
    }
    internal DataTemplate HeaderTemplate = (DataTemplate)XamlReader.Load(
       @"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
               <NavigationViewItemHeader Content='{Binding Name}' />
              </DataTemplate>");

    internal DataTemplate SeparatorTemplate = (DataTemplate)XamlReader.Load(
        @"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
                <NavigationViewItemSeparator />
              </DataTemplate>");
}

c# - UWP-在NavigationViewItems上设置IsEnabled-LMLPHP

更新一首

问题的关键在于我们无法在1803年使用DataTemplate。通常,为了在1803年创建NavigationViewItem,我们经常使用以下解决方案。

Xaml
<NavigationView x:Name="nvSample" MenuItemsSource="{x:Bind NavItems}" >

</NavigationView>

背后的代码
public ObservableCollection<Category> Categories { get; set; }
public MainPage()
{
    this.InitializeComponent();
    Categories = new ObservableCollection<Category>();
    Categories.Add(new Category { Name = "Category 1", Glyph = Symbol.Home, Tooltip = "This is category 1", IsEnabled = false });
    Categories.Add(new Category { Name = "Category 2", Glyph = Symbol.Keyboard, Tooltip = "This is category 2", IsEnabled = true });
    Categories.Add(new Category { Name = "Category 3", Glyph = Symbol.Library, Tooltip = "This is category 3", IsEnabled = true });
    Categories.Add(new Category { Name = "Category 4", Glyph = Symbol.Mail, Tooltip = "This is category 4", IsEnabled = true });

}
public IEnumerable<NavigationViewItemBase> NavItems
{
    get
    {
        return Categories.Select(
               b => (new NavigationViewItem
               {
                   Content = b.Name,
                   Icon = new SymbolIcon(b.Glyph),
                   IsEnabled = b.IsEnabled,
               })
        );
    }
}

简而言之,我们需要将数据模型转换为NavigationViewItem。但不要在1803年内使用DataTemplate。请尝试此操作。有关更多详细信息,您也可以引用此case

关于c# - UWP-在NavigationViewItems上设置IsEnabled,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53951958/

10-10 07:04