【问题标题】:How do you create Xamarin Forms class hierarchies inheriting from the 'Page' type?如何创建从“页面”类型继承的 Xamarin Forms 类层次结构?
【发布时间】:2017-06-30 08:09:08
【问题描述】:

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

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

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

这两个页​​面都是带有代码隐藏的 xaml 页面,但 PageB 页面无法正常工作,我不知道为什么(我是 XAML、Xamarin、C# 的新手,基本上是一般的编码)。

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

this.FindByName<Label>

给我一​​个警告:

PageB 不包含“FindByName”的定义,最好的扩展方法...需要一个“元素”类型的接收器

还有这一行:

await Navigation.PushAsync(new PageB());

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

问题:

  1. 是否可以创建自定义页面的子类?
  2. 为什么将 ContentPage (PageA) 子类的类视为“元素”类型和“页面”类型?为什么 PageB 不属于这些类型?

我怀疑我在这里的很多事情都非常偏离,所以非常欢迎我对问题的措辞方式进行任何更正,并指出我应该问什么问题!

===========编辑

回应以下评论:

PageA

.cs 文件(代码隐藏)具有命名空间 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>

PageB

.cs 文件(代码隐藏)具有命名空间 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>

【问题讨论】:

  • 能否也分享一下 Xaml 代码?以及后面代码的命名空间?

标签: c# xamarin xamarin.forms


【解决方案1】:

试试这个

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

如下创建一个基本页面

<?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】:

    这是Krishna's excellent answer 的细微变化。
    (我会写评论,但我想清楚地显示代码更改。)

    BasePage.xaml 不需要;只需在BasePage.xaml.cs 中执行此操作:

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

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

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

    所以,派生页面C#变成:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-18
      • 1970-01-01
      • 2020-08-30
      • 1970-01-01
      相关资源
      最近更新 更多