UWP - 防止 NavigationViewItemHeader 被剪裁

UWP - Prevent NavigationViewItemHeader from being clipped

我正在编写一个 UWP 应用程序,它有一个包含 NavigationViewItemHeaderNavigationView

   <NavigationView.MenuItems>
        <NavigationViewItem Content="Home" Tag="home">
            <NavigationViewItem.Icon>
                <FontIcon Glyph="&#xE80F;"/>
            </NavigationViewItem.Icon>
        </NavigationViewItem>

        <NavigationViewItemSeparator/>
        <NavigationViewItemHeader x:Name="ThemesHeading" Content="Themes"/>

        <NavigationViewItem Content="Themes" Tag="themes">
            <NavigationViewItem.Icon>
                <FontIcon Glyph="&#xE771;"/>
            </NavigationViewItem.Icon>
        </NavigationViewItem>

(以此类推)

然而,当我折叠视图时,headers 被剪掉了:

我应该怎么做才能防止这种情况发生?

定义 NavigationView 对象的名称属性 x:Name,这样您就可以访问它的 IsPaneOpen 属性。使用 Binding 属性 ElementName 来获取要用作绑定源的元素,以及使用属性定义的唯一标识符。

顾名思义,IsPaneOpen属性 标识窗格是否打开到全宽,可用于切换 NavigationViewItemHeader.Visibility[=69= 的可见性]!

<NavigationView x:Name="NavView" ... >

    <NavigationViewItemHeader x:Name="ThemesHeading" Content="Themes" 
            Visibility="{Binding IsPaneOpen, 
                        ElementName=NavView, 
                        Converter={StaticResource BoolToVis}}"/>

</NavigationView>

由于 IsPaneOpen 属性 returns 是一个 Boolean 值,而 VisibilityEnum 类型,您需要创建一个转换器,因此您的布尔状态可以分配给对可见性有意义的值 属性。 对于我们的情况,我们想要:

NavigationView.IsPaneOpen = True -> NavigationViewItemHeader.Visibility = Visibility.Visible;

NavigationView.IsPaneOpen = False -> NavigationViewItemHeader.Visibility = Visibility.Collapsed;

默认情况下绑定的模式设置为 OneWay,这正是您想要的,因为您的 NavigationView 将决定 NavigationViewItemHeader 的视觉状态,而您不需要反过来。

创建一个 class,它将成为您的转换器!您的 class 必须继承自 IValueConverter 接口。在我的例子中,我创建了一个名为 "Converter" 的文件夹并在那里定义了 BooleanToVisibilityConverter。

namespace MyUWPApplication.Converter
{
    class BooleanToVisibilityConverter : IValueConverter
    {
        public BooleanToVisibilityConverter()
        {
        }

        public object Convert(object value, Type targetType, object parameter, string language)
        {
            if (value is bool && (bool)value)
            {
                return Visibility.Visible;
            }
            return Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
}

在您的 XAML 页面中包含上面的 Namespace您的页面会有所不同),如下所示:

xmlns:common="using:MyUWPApplication.Converter"

下面,定义你的 Converter 资源并给它一个键,这样你就可以在 Binding 定义中引用它。

            <Page.Resources>
                <common:BooleanToVisibilityConverter x:Key="BoolToVis" />
            </Page.Resources>

Binding 定义中引用了转换器资源 BoolToVis,每当 IsPaneOpen 属性 发生变化时,将调用 Convert 函数进行转换我们的布尔值可见性。

结果:

解决方案 1

增加项目的左边距 headers:

<NavigationViewItemHeader Content="Themes" Margin="33,0,0,0"/>
...
<NavigationViewItemHeader Content="Builds" Margin="33,0,0,0"/>

解决方案 2

通过将 CompactModeThresholdWidthExpandedModeThresholdWidth 设置为某个较大的数字来禁用 NavigationView 的紧凑和扩展显示模式:

<NavigationView CompactModeThresholdWidth="100000" ExpandedModeThresholdWidth="100000">

解决方案 3

按照 André B 的建议,将项目 headers 的 Visibility 属性 绑定到 NavigationViewIsPaneOpen 属性,仅使用x:Bind 而不是 Binding 因为它不需要转换器:

<NavigationView Name="MyNavigationView">
    ...
            <NavigationViewItemHeader Content="Themes" Visibility="{x:Bind MyNavigationView.IsPaneOpen, Mode=OneWay}"/>
    ...
            <NavigationViewItemHeader Content="Builds" Visibility="{x:Bind MyNavigationView.IsPaneOpen, Mode=OneWay}"/>
    ...
</NavigationView>