如何创建继承自"页面"类型的Xamarin Forms类层次结构?

Zac*_*ith 4 c# xamarin xamarin.forms

在Xamarin.Forms中,我正在尝试创建一个我然后子类化的页面,如下所示:

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

public partial class PageB : PageA {
  public PageB() : base() { ... }
}
Run Code Online (Sandbox Code Playgroud)

这两个页面都是包含代码隐藏的xaml页面,但是PageB页面不起作用,我不知道为什么(我是XAML,Xamarin,C#的新手,基本上是编码).

我目前无法编译代码,因为这一行:

this.FindByName<Label>
Run Code Online (Sandbox Code Playgroud)

给我一个警告:

PageB不包含'FindByName'的定义,最好的扩展方法......需要'Element'类型的接收器

这一行:

await Navigation.PushAsync(new PageB());
Run Code Online (Sandbox Code Playgroud)

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

问题:

  1. 是否可以创建自定义页面的子类?
  2. 为什么子类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>
Run Code Online (Sandbox Code Playgroud)

网页B

.cs文件(codebehind)具有命名空间AppName.FolderName.SubFolderName,xaml具有x:Class属性值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>
Run Code Online (Sandbox Code Playgroud)

Kri*_*hna 5

试试这个

仅供参考,此代码来自我的应用程序,这是一个工作示例

创建一个基页,如下所示

<?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>
Run Code Online (Sandbox Code Playgroud)

你的基页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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在派生的页面看起来像这样

<?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>
Run Code Online (Sandbox Code Playgroud)

派生页面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
    {
    }
}
Run Code Online (Sandbox Code Playgroud)


Too*_*eve 5

这与克里希纳的出色答案略有不同。
(我本来可以将其作为注释,但我想清楚地显示代码更改。)

如果 BasePage 没有在 XAML 中定义任何元素(请参阅 Krishna 的回答 -<views:BasePage>没有子元素),则BasePage.xaml 不需要THEN ;只需在以下位置执行此操作BasePage.xaml.cs

using Xamarin.Forms;

public abstract class BasePage : ContentPage
{
    public BasePage()
    {
        // Each sub-class calls InitializeComponent(); not needed here.
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您的子页面必须调用InitializeComponent();,就像您通常在 ContentPage 构造函数中所做的那样。

InitializeComponent();我认为这是更好的设计,因为在派生页面构造函数中看不到会令人惊讶;让读者想知道它是否应该在那里,但不小心被遗漏了。这就是我使用这种变体的原因。每个页面声明看起来就像一个普通的内容页面,只不过它继承自 BasePage 而不是 ContentPage。
在常规内容页面和此子类之间来回更改很简单。
我通过使用 ContentPage 的 xamarin 表单模板创建其中之一,然后在 C# 和 XAML 中将基类更改为 BasePage。

因此,派生页面 C# 变为:

public partial class LoginPage : BasePage
{
    public LoginPage()
    {
        InitializeComponent();
    }
}
Run Code Online (Sandbox Code Playgroud)

派生页面 XAML 如 Krishna 的回答所示。