如何自定义XAML导航视图窗格的外观

uxhixvfz  于 2023-03-06  发布在  其他
关注(0)|答案(2)|浏览(182)

我有一个XAML导航视图控件与“顶部”PaneDisplayMode。
我想增加窗格高度并居中对齐菜单项。
增加NavigationViewItem高度不会使窗格变高。更改对齐设置不会影响菜单项在窗格中的位置。
我该怎么做呢?

<Page ... xmlns:muxc="using:Microsoft.UI.Xaml.Controls" ... >
<Grid>
    <muxc:NavigationView x:Name="NavView"
                         Loaded="NavView_Loaded"
                         ItemInvoked="NavView_ItemInvoked"
                         BackRequested="NavView_BackRequested"
                         PaneDisplayMode="Top">

        <muxc:NavigationView.MenuItems>
            <muxc:NavigationViewItem Tag="home" Icon="Home" Content="Home"/>
            <muxc:NavigationViewItemSeparator/>
            <muxc:NavigationViewItemHeader x:Name="MainPagesHeader"
                                           Content="Main pages"/>
            <muxc:NavigationViewItem Tag="apps" Content="Apps">
                <muxc:NavigationViewItem.Icon>
                    <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xEB3C;"/>
                </muxc:NavigationViewItem.Icon>
            </muxc:NavigationViewItem>
            <muxc:NavigationViewItem Tag="games" Content="Games">
                <muxc:NavigationViewItem.Icon>
                    <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE7FC;"/>
                </muxc:NavigationViewItem.Icon>
            </muxc:NavigationViewItem>
            <muxc:NavigationViewItem Tag="music" Icon="Audio" Content="Music"/>
        </muxc:NavigationView.MenuItems>

    

        <ScrollViewer>
            <Frame x:Name="ContentFrame" Padding="12,0,12,24" IsTabStop="True"
                   NavigationFailed="ContentFrame_NavigationFailed"/>
        </ScrollViewer>
    </muxc:NavigationView>

</Grid>
</Page>
3pvhb19x

3pvhb19x1#

您可以通过VisualTreeHelper类获取子网格来自定义NavigationView的外观。

private void NavigationView_Loaded(object sender, RoutedEventArgs e)

{ //使用muxc =微软.UI.Xaml.控件;

var navView = sender as muxc.NavigationView;
var rootGrid = VisualTreeHelper.GetChild(navView, 0) as Grid;
// From the root grid, you can get child elements to customize them.
// You can view the NavigationView diagram from the NavigationView link above.

// Find the top navigation pane and set properties.
var grid = VisualTreeHelper.GetChild(rootGrid, 1) as Grid;
var topNavArea = VisualTreeHelper.GetChild(grid, 0) as StackPanel;
var topNavGrid = VisualTreeHelper.GetChild(topNavArea, 1) as Grid;

topNavGrid.Height = ...;
topNavGrid.RowDefinitions = ...;

}
您必须找到导航视图查尔兹视图的路径,并且您应该有一种方法来自定义导航视图项,如上所述。
您可以使用Visual Studio中的可视化树检查器来检查导航视图并了解子元素。See Here我向Bing AI询问了有关检查UWP应用的可视化树的问题,他给了我那个链接。
在XAML中自定义NavigationView外观的另一种方法是使用Control模板和setter属性。

<NavigationView x:Name="NavView">
<NavigationView.Style>
    <Style TargetType="NavigationView" BasedOn="{StaticResource DefaultNavigationViewStyle}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="NavigationView">
                    <!-- Copy the default template here -->
                    <!-- Find NavigationViewTopPane and change its Height -->
                    <Grid x:Name="NavigationViewTopPane" Height="60">
                        <!-- Other elements -->
                    </Grid>
                    <!-- Find TopNavMenuItemsOverflowHost and change its VerticalAlignment -->
                    <ListView x:Name="TopNavMenuItemsOverflowHost" VerticalAlignment="Center">
                        <!-- Other elements -->
                    </ListView>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</NavigationView.Style>

如果您没有找到“DefaultNavigationViewStyle”,您必须将其添加到应用程序合并资源中。

4jb9z9bj

4jb9z9bj2#

找不到答案,所以通过删除导航视图和实现类似的东西来解决它,在这里分享,以防其他人也遇到同样的困境。所以这更多的是一个变通办法,而不是一个答案。如果有人提供了一个更好的答案,我会接受它。
在NavigationRoot.xaml中,我有一个带有堆栈面板的网格用于“窗格”,框架用于页面。注意,按钮有一个与我在导航中使用的页面标签相匹配的标签(不要判断)。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="4*"/>
    </Grid.RowDefinitions>

    <StackPanel x:Name="Pane" Orientation="Horizontal" HorizontalAlignment="Center" Margin="10">
        <ToggleButton  x:Name="HomeButton" Content="Home"  Tag="home" Click="Button_Click" Width="100" Margin="10"/>
        <ToggleButton  x:Name="SettingsButton" Content="Settings" Tag="settings" Click="Button_Click" Width="100" Margin="10"/>
    </StackPanel>
    <Frame Grid.Row="1" x:Name="RootContentFrame"/>
</Grid>

在代码后面我跟踪“CurrentPageTag”,我有一个页面列表。

private string CurrentPageTag;
    
    // List of ValueTuple holding the Navigation Tag and the relative Navigation Page
    private readonly List<(string Tag, Type Page)> _pages = new List<(string Tag, Type Page)>
    {
        ("home", typeof(MainPage)),
        ("settings", typeof(SettingsPage))
    };

在切换按钮的button_click事件中,我获得了button标记并导航到该页面:

string TargetPageTag = (sender as ToggleButton).Tag.ToString();
 //cancel navigation of current and target are the same
 if (TargetPageTag == CurrentPageTag)
 {
     return;
 }
 else
 {
       /*
       you can check that page can be navigated away from here (form 
       validation and the like) and exit early if validation fails. 
       I actually use a global "cancel navigation" variable 
       that pages can set if they are in an incomplete state 
       and should not be navigated away from.
       */
 
   //navigate to target page
   Type targetPage = _pages.FirstOrDefault(p => p.Tag.Equals(targetPageTag)).Page;
   RootContentFrame.Navigate(targetPage);
   CurrentPageTag = targetPageTag;
   return;
 }

这为您提供了基本的“导航视图”之类的功能,实际上代码堆更少(但不能动态更改窗格布局)。
我在这里为了简洁而省略的是,我必须设计切换按钮的样式以更适合这个目的。而且,我让它们更像单选按钮一样工作,在任何时候只有一个被选中。也许单选按钮应该使用更多的样式(但我讨厌样式,所以走了这条路)?

相关问题