UWP NavigationView Header 标题
UWP NavigationView Header Title
我正在尝试使用 NavigationView
制作 UWP 应用。我的问题是找到一种方法来更改当前显示页面的 Header
。我的应用基于 Microsoft UWP 示例 "AppUIBasics"。在示例中,NavigationView
的 Header
始终显示 "Welcome",因为它是硬编码的,但我希望它根据所选页面进行更改。
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=""/>
</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;
}
}
}
首先,您必须 "un-hardcode" 模板中的 header 文本,您可以使用 {Binding}
代替文本,这将提供分配给 [=18= 的值]的Header
属性:
<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>
简单的解决方案
现在有两个地方可以设置header内容。首先是 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 方法从任何地方设置 Header
public void SetHeader(string header)
{
NavView.Header = header;
}
然后在您认为合适的地方使用 MainPage.Current.SetHeader( something )
。
最佳解决方案
然而,最好的解决方案是创建一个基础 class 其他页面将派生自:
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
中我们使用 data-binding 将 Header
属性 绑定到 NavigationView
的 Header
:
<NavigationView x:Name="NavView"
Header="{Binding Path=Content.Header, ElementName=rootFrame}" ...>
第 1 步
定义接口
interface ISubPage
{
string NavTitile { get; }
}
第 2 步
在sub-page实现这个接口
public sealed partial class HomePage : Page, ISubPage
{
public HomePage()
{
InitializeComponent();
}
public string NavTitile => "ArticlePage";
}
第 3 步
<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>
我正在尝试使用 NavigationView
制作 UWP 应用。我的问题是找到一种方法来更改当前显示页面的 Header
。我的应用基于 Microsoft UWP 示例 "AppUIBasics"。在示例中,NavigationView
的 Header
始终显示 "Welcome",因为它是硬编码的,但我希望它根据所选页面进行更改。
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=""/>
</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;
}
}
}
首先,您必须 "un-hardcode" 模板中的 header 文本,您可以使用 {Binding}
代替文本,这将提供分配给 [=18= 的值]的Header
属性:
<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>
简单的解决方案
现在有两个地方可以设置header内容。首先是 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 方法从任何地方设置Header
public void SetHeader(string header)
{
NavView.Header = header;
}
然后在您认为合适的地方使用 MainPage.Current.SetHeader( something )
。
最佳解决方案
然而,最好的解决方案是创建一个基础 class 其他页面将派生自:
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
中我们使用 data-binding 将 Header
属性 绑定到 NavigationView
的 Header
:
<NavigationView x:Name="NavView"
Header="{Binding Path=Content.Header, ElementName=rootFrame}" ...>
第 1 步
定义接口
interface ISubPage
{
string NavTitile { get; }
}
第 2 步
在sub-page实现这个接口
public sealed partial class HomePage : Page, ISubPage
{
public HomePage()
{
InitializeComponent();
}
public string NavTitile => "ArticlePage";
}
第 3 步
<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>