我有一个带有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"
>
我想将创建的
IsEnabled
的NavigationViewItems
属性绑定(bind)到NavigationViewElement
上的属性。我该怎么办?我对
ListBox
也有类似的问题。在这种情况下,我能够从ListBox派生一个新类,该类重写PrepareContainerForItemOverride()
并根据绑定(bind)到其的类中的数据设置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);
}
是否有
NavigationView?
的等效项?是否有其他方法表明IsEnabled
的NavigationViewItem
标志应绑定(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=}" 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的内容:
正是我所需要的,但是我不知道如何将项目的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。单击带有文本的区域无济于事-我必须单击浅灰色区域之外的项目才能进行导航。
对我在做什么错有任何见解吗?总之,我希望找到一种既可以自定义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>");
}
更新一首
问题的关键在于我们无法在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/