代码之家  ›  专栏  ›  技术社区  ›  Zach Smith

如何创建从“页面”类型继承的Xamarin表单类层次结构?

  •  5
  • Zach Smith  · 技术社区  · 7 年前

    在Xamarin。表单,我试图创建一个页面,然后将其子类化,如下所示:

    public partial class PageA : ContentPage {
      public PageA() {InitializeComponent ();}
    }
    
    public partial class PageB : PageA {
      public PageB() : base() { ... }
    }
    

    我现在无法编译代码,因为这行代码:

    this.FindByName<Label>
    

    给我一个警告:

    PageB不包含“FindByName”的定义,最佳扩展方法…需要“Element”类型的接收器

    这一行:

    await Navigation.PushAsync(new PageB());
    

    给出一个错误,即PageB不是Xamarin.Forms.Page。我不知道为什么PageA会被认为是这样的一种类型,但它确实是。

    问题:

    1. 为什么将ContentPage(PageA)的子类同时视为“Element”类型和“Page”类型的类?为什么PageB不属于这些类型?

    =======编辑

    第A页

    cs文件(codebehind)具有命名空间 AppName.FolderName ,并且xaml具有x:Class属性值 x:Class="AppName.FolderName.PageA"

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="AppName.FolderName.PageA">
    
                 ... (some elements) ...
    
    </ContentPage>
    

    第B页

    cs文件(codebehind)具有命名空间 AppName.FolderName.SubFolderName x:Class="AppName.FolderName.SubFolderName.PageB"

    我有以下参考资料 using AppName.FolderName ,这使我可以访问 PageA

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="AppName.FolderName.SubFolderName.PageB">
    </ContentPage>
    
    2 回复  |  直到 7 年前
        1
  •  7
  •   Krishna    7 年前

    试试这个

    创建一个基本页面,如下所示

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Sthotraani.Views.BasePage">
    
    </ContentPage>
    

    您的主页cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using Xamarin.Forms;
    
    namespace Sthotraani.Views
    {
        public partial class BasePage : ContentPage
        {
            public BasePage()
            {
                InitializeComponent();
            }
        }
    }
    

    <?xml version="1.0" encoding="utf-8" ?>
    <views:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    xmlns:views="clr-namespace:Sthotraani.Views;assembly=Sthotraani"
                    x:Class="Sthotraani.Views.LoginPage"
                    BackgroundColor="#009688"
                    xmlns:controls="clr-namespace:Sthotraani.CustomControls;assembly=Sthotraani"
                    xmlns:converters="clr-namespace:Sthotraani.Converters;assembly=Sthotraani"
                    xmlns:behaviors="clr-namespace:Sthotraani.Behaviors;assembly=Sthotraani">
    
    </views:BasePage>
    

    派生页面cs如下所示

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using Xamarin.Forms;
    
    namespace Sthotraani.Views
    {
        public partial class LoginPage : BasePage
        {
        }
    }
    
        2
  •  4
  •   ToolmakerSteve    2 年前

    这是对 Krishna's excellent answer
    (我本想对此发表评论,但我想清楚地展示代码的变化。)

    如果BasePage没有在XAML中定义任何元素(参见Krishna的回答- <views:BasePage> 没有孩子),那么 BasePage.xaml 不需要 ; 只需在 BasePage.xaml.cs :

    using Xamarin.Forms;
    
    public abstract class BasePage : ContentPage
    {
        public BasePage()
        {
            // Each sub-class calls InitializeComponent(); not needed here.
        }
    }
    

    那么您的子页面必须调用 InitializeComponent();

    InitializeComponent(); 在派生页面构造函数中;让读者怀疑 应该 但意外地被遗漏了。这就是我使用这个变体的原因。
    在常规内容页和该子类之间来回更改很简单。
    我使用xamarin表单模板为ContentPage创建了其中一个,然后在C#和XAML中将基类更改为BasePage。

    因此,导出页面C#变为:

    public partial class LoginPage : BasePage
    {
        public LoginPage()
        {
            InitializeComponent();
        }
    }
    

    导出的XAML页面如奎师那的回答所示。