【问题标题】:UWP NavigationView Header TitleUWP NavigationView 标题标题
【发布时间】:2018-08-09 15:27:40
【问题描述】:

我正在尝试使用 NavigationView 制作 UWP 应用。我的问题是找到Header 更改当前显示页面的方法。我的应用基于 Microsoft UWP 示例“AppUIBasics”。在示例中,NavigationViewHeader 始终显示“欢迎”,因为它是硬编码的,但我希望它根据所选页面进行更改。

MainPage.xaml

 <NavigationView x:Name="NavView"
                ItemInvoked="NavView_ItemInvoked"
                SelectionChanged="NavView_SelectionChanged"
                Loaded="NavView_Loaded"
                Canvas.ZIndex="0">

    <NavigationView.HeaderTemplate>
        <DataTemplate>
            <Grid Margin="24,10,0,0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <TextBlock x:Name="appTitle" Style="{StaticResource TitleTextBlockStyle}"
                       FontSize="28"
                       VerticalAlignment="Center"
                       Text="Welcome"/>
                <CommandBar Grid.Column="1"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Top"
                        DefaultLabelPosition="Right"
                        Background="{ThemeResource SystemControlBackgroundAltHighBrush}">
                    <AppBarButton Label="Refresh" Icon="Refresh"/>
                    <AppBarButton Label="Import" Icon="Import"/>
                </CommandBar>
            </Grid>
        </DataTemplate>
    </NavigationView.HeaderTemplate>

    <NavigationView.MenuItems>
        <NavigationViewItem x:Uid="HomeNavItem" Content="" Tag="home">
            <NavigationViewItem.Icon>
                <FontIcon Glyph="&#xE10F;"/>
            </NavigationViewItem.Icon>
        </NavigationViewItem>
        <NavigationViewItemSeparator/>
        <NavigationViewItem x:Uid="ConnectionNavItem" Icon="world" Content="" Tag="connection"/>
        <NavigationViewItem x:Uid="CameraNavItem" Icon="video" Content="" Tag="camera"/>
    </NavigationView.MenuItems>

    <Frame x:Name="rootFrame" Margin="24">
        <Frame.ContentTransitions>
            <TransitionCollection>
                <NavigationThemeTransition/>
            </TransitionCollection>
        </Frame.ContentTransitions>
    </Frame>

</NavigationView>

MainPage.xaml.cs

 public sealed partial class MainPage : Page {
    public static MainPage Current;
    public static Frame RootFrame = null;

    //private RootFrameNavigationHelper _navHelper;
    private ResourceLoader _resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();

    public MainPage() {
        this.InitializeComponent();

        this.Loaded += (sender, args) => {
            Current = this;
            var titleBar = Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().TitleBar;
        };
    }

    public Frame AppFrame { get { return this.rootFrame; } }

    private void NavView_Loaded(object sender, RoutedEventArgs e) {
        // set the initial SelectedItem 
        foreach (NavigationViewItemBase item in NavView.MenuItems) {
            if (item is NavigationViewItem && item.Tag.ToString() == "home") {
                NavView.SelectedItem = item;
                break;
            }
        }
    }

    private void NavView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args) {

        if (args.IsSettingsInvoked) {
            rootFrame.Navigate(typeof(SettingsPage));
        } else {
            // find NavigationViewItem with Content that equals InvokedItem
            var item = sender.MenuItems.OfType<NavigationViewItem>().First(x => (string)x.Content == (string)args.InvokedItem);
            NavView_Navigate(item as NavigationViewItem);

        }
    }

    private void NavView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args) {
        if (args.IsSettingsSelected) {
            rootFrame.Navigate(typeof(SettingsPage));
        } else {
            NavigationViewItem item = args.SelectedItem as NavigationViewItem;
            NavView_Navigate(item);
        }
    }

    private void NavView_Navigate(NavigationViewItem item) {
        switch (item.Tag) {
            case "home":
                rootFrame.Navigate(typeof(HomePage)); break;
            case "connection":
                rootFrame.Navigate(typeof(ConnectionPage)); break;
            case "camera":
                rootFrame.Navigate(typeof(CameraPage)); break;
        }
    }
}

【问题讨论】:

    标签: c# uwp navigationview


    【解决方案1】:

    首先,您必须从模板中“取消硬编码”标题文本,而不是文本,您可以使用 {Binding},它将提供分配给 NavigationViewHeader 属性的值:

    <NavigationView.HeaderTemplate>
        <DataTemplate>
            <Grid Margin="24,10,0,0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <TextBlock x:Name="appTitle" Style="{StaticResource TitleTextBlockStyle}"
                    FontSize="28"
                    VerticalAlignment="Center"
                    Text="{Binding}"/>
                <CommandBar Grid.Column="1"
                    HorizontalAlignment="Right"
                    VerticalAlignment="Top"
                    DefaultLabelPosition="Right"
                    Background="{ThemeResource SystemControlBackgroundAltHighBrush}">
                    <AppBarButton Label="Refresh" Icon="Refresh"/>
                    <AppBarButton Label="Import" Icon="Import"/>
                </CommandBar>
            </Grid>
        </DataTemplate>
    </NavigationView.HeaderTemplate>
    

    简单的解决方案

    现在有两个地方可以设置标题内容。首先是SelectionChanged事件:

    private void NavView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
    {
        if (args.IsSettingsSelected)
        {
            rootFrame.Navigate(typeof(SettingsPage));
            NavView.Header = "Settings";
        }
        else
        {
            NavigationViewItem item = args.SelectedItem as NavigationViewItem;
            NavView_Navigate(item);
            //just example, maybe you want to Content or something else
            NavView.Header = item.Tag.ToString(); 
        }
    }
    

    更好的解决方案

    您还可以通过添加设置标头的公共方法从任何地方设置Header

    public void SetHeader(string header)
    {
        NavView.Header = header;
    }
    

    然后在您认为合适的任何地方使用MainPage.Current.SetHeader( something )

    最佳解决方案

    然而,最好的解决方案是创建一个其他页面将派生自的基类:

    public class BasePage : Page
    {
        public virtual string Header => "";
    }
    

    然后每个具体的页面都可以覆盖这个属性:

    public sealed partial class HomePage : BasePage
    {
        public override string Header => "Home";
    
        public HomePage()
        {
            this.InitializeComponent();
        }
    }
    

    注意 - 请记住,您还必须在 XAML 中更新页面的基本类型:

    <local:BasePage xmlns:local="using:AppNamespace"
        x:Class="AppNamespace.HomePage" ...>
    </local:BasePage>
    

    然后在MainPage 中,我们使用数据绑定将Header 属性绑定到NavigationViewHeader

    <NavigationView x:Name="NavView"
                    Header="{Binding Path=Content.Header, ElementName=rootFrame}" ...>
    

    【讨论】:

    • 感谢您的解决方案并纠正我的问题 :)
    • 当然,很高兴它有帮助:-)!编码愉快!
    • 您好,这个答案有问题吗?我看到你取消选中它已解决
    • 其他用户只是复制了我的解决方案,您为什么要接受他的解决方案?
    • 嗯,对不起,我以为我可以检查这两个答案作为解决方案。但为什么他的答案是你的副本?
    【解决方案2】:

    步骤 1

    定义接口

    interface ISubPage
    {
        string NavTitile { get; }
    }
    

    第二步

    在子页面中实现这个接口

    public sealed partial class HomePage : Page, ISubPage
    {
        public HomePage()
        {
            InitializeComponent();
        }
    
        public string NavTitile => "ArticlePage";
    }
    

    第三步

    <NavigationView x:Name="NavView" Header="{Binding Path=Content.NavTitile, ElementName=ContentFrame}">
        <NavigationView.MenuItems>
            <NavigationViewItem Icon="Home" Tag="Home" Content="Home"/>
        </NavigationView.MenuItems>
    
        <Frame x:Name="ContentFrame" Margin="24"/>
    </NavigationView>
    

    【讨论】:

    • 你基本上只是在我的解决方案被接受后复制了它,为什么?
    • 你启发了我,谢谢。我觉得用interface来解决更好
    • 这比其他答案简洁易读,直截了当。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 2020-05-11
    • 1970-01-01
    • 2018-07-02
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    相关资源
    最近更新 更多