【问题标题】:How do I set a Tag attribute to a typeof(Page) in XAML for UWP application?如何在 UWP 应用程序的 XAML 中将 Tag 属性设置为 typeof(Page)?
【发布时间】:2018-08-04 02:16:44
【问题描述】:

如何在 XAML 中为 UWP 应用程序设置 Tag 属性(System.Object 类型)为页面类型?

特别是我在 XAML 中声明 NavigationViewItem,我想将它的 Tag 设置为 Page 的类型,例如

<NavigationViewItem Icon="Home" Content="Home" Tag=views:HomePage />

在 C# 中,我会编写类似 navItem.Tag = typeof(HomePage) 的代码。

请注意,我不是试图将标签设置为页面的实例,而是设置页面的类型。 如果我引用 views:HomeView 部分,它将被存储为字符串。我之前声明了 views 命名空间:

xmlns:views="using:MyApp.Views"

如何在 XAML 中为 typeof(Page) 的属性分配值?谢谢。

【问题讨论】:

    标签: uwp-xaml


    【解决方案1】:

    从 NavigationViewItem 派生一个类,添加一个 Type 类型的 Tag 属性,并使用 new 关键字隐藏继承的 Object 类型的 Tag 属性。

    public class NavigationViewItemEx : NavigationViewItem
    {
       public new Type Tag { get; set; }
    }
    

    您需要限定 XAML 中的类型。页面顶部有其他命名空间 xmlns:local="using:App1" 然后在页面内容本身使用以下内容:

    <NavigationView SelectionChanged="NavigationView_OnSelectionChanged">
      <NavigationView.MenuItems>
         <local:NavigationViewItemEx Icon="Home" Content="Home" TargetPageType="local:MainPage" />
          ...
    </NavigationView>
    

    像往常一样处理 OnSelectionChanged 事件,但将 SelectedItem 转换为您的新类而不是 NavigationViewItem。

    private void NavigationView_OnSelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
    {
       NavigationViewItemEx selectedItem = args.SelectedItem as NavigationViewItemEx;
       Type targetPageType = selectedItem?.Tag;
       //null checking, etc. here
       yourFrame.Navigate(targetPageType);
       ...
    

    这回答了这个问题,但有些人不喜欢隐藏继承的属性,因此使用不同的属性(例如TargetPageType)而不是 Tag 可能更受欢迎。

    【讨论】:

      【解决方案2】:

      不确定为什么要为标签分配 Page 对象,但您可以尝试使用 data binding 将 Page 对象绑定到您的 NavigationViewItem

      Page.xaml:

      <Grid>
          <NavigationView Name="Nav" ItemInvoked="Nav_ItemInvoked">
              <NavigationView.MenuItems>
                  <NavigationViewItem Icon="Home" Content="Home" Tag="{x:Bind PageCollection[0]}"/>
              </NavigationView.MenuItems>
          </NavigationView>
      </Grid>
      

      后面的代码:

      public MainPage()
      {
          this.InitializeComponent();
          PageCollection = new ObservableCollection<Page>();
          //Add page instances
          BlankPage1 blankPage1 = new BlankPage1();
          PageCollection.Add(blankPage1);
      }
      
      public ObservableCollection<Page> PageCollection { get; set; }
      
      private void Nav_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
      {
          var item = sender.MenuItems[0] as NavigationViewItem;
          Debug.WriteLine(item.Tag.GetType());
      }
      

      ---更新---

      如果要将标签设置为Type,可以将类型放入集合中,然后将Type项绑定到标签。所以后面的代码应该是这样的:

      public MainPage()
      {
          this.InitializeComponent();
          PageCollection = new ObservableCollection<Type>();
          //Add page type so that you can bind and navigate to the tag page.
          PageCollection.Add(typeof(BlankPage1));
      }
      
      public ObservableCollection<Type> PageCollection { get; set; }
      
      private void Nav_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
      {
          var item = sender.MenuItems[0] as NavigationViewItem;
          Debug.WriteLine(item.Tag.GetType());
          Frame.Navigate((Type)item.Tag);
      }
      

      ---更新2---

      如果你不想在后面的代码中使用数据绑定,我可以考虑在你的页面中使用资源添加一个对象,然后你可以使用你的标签来引用它。

      <Page.Resources>
          <local:BlankPage1 x:Key="Page1" />
      </Page.Resources>
      <NavigationView ItemInvoked="Nav_ItemInvoked">
          <NavigationView.MenuItems>
              <NavigationViewItem Icon="Home" Content="Home" Tag="{StaticResource Page1}" />
          </NavigationView.MenuItems>
      </NavigationView>
      

      然后就可以通过标签导航到页面了,

      Frame.Navigate(navItem.Tag.GetType());
      

      【讨论】:

      • 我不清楚。我不想将 Tag 设置为页面的实例,而是设置为页面的类型。然后可以使用 Frame.Navigate(navItem.Tag) 进行导航。我见过的所有示例都需要将字符串标签映射到要导航到的页面类型,我想避免混乱的映射。
      • @CoderBrian 我已经在我的答案中添加了更新部分,您可以创建一个包含 Type 类型项目的 Collection,以便您可以使用 Tag 绑定和导航到页面。
      • 似乎应该有一种方法单独在 XAML 中(即没有代码背后或投标)来引用 TypePage。有什么想法吗?
      • 好的,我已经根据您的要求添加了 Update 2 部分,以避免使用代码隐藏或绑定。
      猜你喜欢
      • 1970-01-01
      • 2012-04-12
      • 2017-04-29
      • 1970-01-01
      • 2015-11-13
      • 2010-12-10
      • 1970-01-01
      • 2019-08-20
      • 1970-01-01
      相关资源
      最近更新 更多