c# - UWP - 在 NavigationViewItems 上设置 IsEnabled
问题描述
我有一个带有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"
>
我想将创建的IsEnabled
属性绑定到. 我该怎么做?NavigationViewItems
NavigationViewElement
我对 a 有类似的问题ListBox
。在这种情况下,我能够从 ListBox 派生一个新类,它根据绑定到的类中的数据(在本例中为 OptionItem)覆盖PrepareContainerForItemOverride()
并设置IsEnabled
标志ListBoxItem
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
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 属性绑定到 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>
然后我可以根据需要绑定 IsEnabled 属性,但 UI 无法正确绘制。该项目的内容似乎在我已经拥有的内容之上添加了第二个 NavigationViewItem。单击带有文本的区域没有任何作用 - 我必须单击浅灰色区域之外的项目才能进行导航。
对我做错了什么有任何见解吗?总之,我希望找到一种方法来自定义 NavigationViewItem 的显示内容,同时还将 IsEnabled 属性绑定到模型中 NavigationViewElement 上的属性。
解决方案
与模型绑定MenuItemsSource
,可以参考官方代码示例。在最新版本中,我们添加了关于设置数据源的新功能MenuItemsSource
。如果要启用或禁用NavigationViewItem
,可以IsEnabled
在模型中创建属性然后绑定它。请检查以下代码。
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>");
}
更新一
问题的关键是我们不能DataTemplate
在1803中使用。一般来说,NavigationViewItem
在1803中创建我们经常使用以下解决方案。
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。请试试这个。有关更多详细信息,您还可以参考此案例。
推荐阅读
- azure - 具有基于策略的站点到站点连接的同一网络上的 Azure 点到站点 VPN
- android - 列表视图下的按钮
- python - 如何在 Python 中验证 application/x-bzip2 类型的响应
- python - When to start the google cloud profiler in a Django project?
- sql - 选择函数索引或新列索引
- python - Django with DEBUG = True and django.contrib.staticfiles not finding static files
- javascript - 折叠展开动画而不转换“高度”属性?
- python - 猴子补丁第三方库
- python - Python unittest模拟类和类方法
- python - 检查输入时出错:预期 conv2d_3_input 的形状为 (64, 64, 3) 但得到的数组的形状为 (64, 64, 1)