简体   繁体   English

从一个 class 中控制 2 个不同的页面 UI

[英]Control 2 different pages UI from within one single class

I know this question may be nonsense, but I've been thinking about it for some time.我知道这个问题可能是无稽之谈,但我已经思考了一段时间。 I am developing a Xamarin Forms app that works both on Windows and on Android, and they share most of the code.我正在开发一个 Xamarin Forms 应用程序,它可以在 Windows 和 Android 上运行,并且它们共享大部分代码。 However, there is a particular page that, for some reasons needs to be platform specific (because of the UI elements distribution that makes the app look weird).但是,由于某些原因,有一个特定的页面需要特定于平台(因为 UI 元素分布使应用程序看起来很奇怪)。 As the number of lines of code increases, and them being almost the same, I came up with the idea of creating a separate script that handles the logic for both pages, and I would simply have to call these new methods from each page.随着代码行数的增加,而且它们几乎相同,我想到了创建一个单独的脚本来处理两个页面的逻辑,我只需从每个页面调用这些新方法即可。 the problem comes here, as I want to modify some UI elements (I've previously created some getters for each UI element), and as each page has a different class name, let's say Page1 and Page2, is there any way that I could set in run time, depending on the platform on which the app is running, a generic variable that can take either Page1 or Page2 type?问题来了,因为我想修改一些 UI 元素(我之前为每个 UI 元素创建了一些 getter),并且每个页面都有不同的 class 名称,比方说 Page1 和 Page2,有什么办法可以根据运行应用程序的平台,在运行时设置一个可以采用 Page1 或 Page2 类型的通用变量?

What I tried我试过的

I have tried with Shared Projects and compilation directives我尝试过共享项目和编译指令

#if WINDOWS_UWP
...
#elif ANDROID
...
#endif

but I don't know if it is me that I don't know how to use it properly, or if it doesn't work at all.但是我不知道是我不知道如何正确使用它,还是根本不起作用。 At compilation time, it says that this generic variable does not have a definition for whatever variable belonging to the Page1 and Page2 classes.在编译时,它表示此通用变量没有属于 Page1 和 Page2 类的任何变量的定义。

My aim is to have something like this我的目标是拥有这样的东西

class Page1{
    int SameVariableName;
}

class Page2{
    int SameVariableName
}

class GenericClass{
    //Check if Platform is Windows or Android
    if (Windows) { Page1 pageVariable = new Page1();}
    else if (Android) { Page2 pageVariable = new Page2();}

    pageVariable.SameVariableName = (...);
}

The problem is that, as the pageVariable assignment is not done until runtime, it gives plenty of compilaiton errors such as pageVariable does not contain a definition for SameVariableName问题是,由于 pageVariable 分配直到运行时才完成,它会产生大量编译错误,例如 pageVariable 不包含 SameVariableName 的定义

Many thanks in advance for reading this and trying to help me非常感谢您阅读本文并试图帮助我

It looks like you should have done this the other way around.看起来你应该反过来做。 Since most of the code is exactly the same, there should be a Page class.由于大部分代码完全相同,所以应该有一个Page class。

Then, you could actually convert Page1 or Page2 into a Page class, so that your generic class handles only a Page class and don't have to deal with Page1 or Page2.然后,您实际上可以将 Page1 或 Page2 转换为 Page class,以便您的通用 class 仅处理 Page class 而不必处理 Page1 或 Page2。 You proceed with the code and then if you need to send them back, convert to other way around.您继续处理代码,然后如果您需要将它们发回,请转换为其他方式。

But honestly, the reel way to do what you are trying to do is learning and using C# interface, using interface you could make a parent class that strategicallly handles both children classes and the problem would have been solved even before being an actual problem.但老实说,做你想做的事情的真正方法是学习和使用 C# 接口,使用接口你可以让父 class 战略性地处理两个子类,这个问题甚至在成为实际问题之前就已经解决了。 You would have a Page class and both Page1 and Page2 would inherit from the Page class. Your compiler will not complain this way.您将拥有一个页面 class,并且页面 1 和页面 2 都继承自页面 class。您的编译器不会以这种方式抱怨。

If you have shared code, have Page1 and Page2 inherit from a BasePage class.如果您有共享代码,让 Page1 和 Page2 从 BasePage class inherit

The differences are done by defining abstract (or virtual , if you need a "base" definition) methods and properties, and implementing those in both Page1 and Page2.差异是通过定义abstract (或virtual ,如果您需要“基本”定义)方法和属性,并在 Page1 和 Page2 中实现它们来实现的。

public abstract class BasePage
{
  abstract SomeType SomePropertyB { get; set; }
  abstract void SomeMethodA();
  public void SomeMethodC()
  {
    // These access values/code that are different, depending on which Page we are in.
    var b = SomePropertyB;
    SomeMethodA();
}
public class Page1 : BasePage
{
  override SomeType SomePropertyB
  {
    get => ...;
    set => ...;
  }
  override void SomeMethodA()
  {
    ...
  }

  // Putting a page into a variable that could be either page.
  BasePage page = new Page1();

If there were no shared implementation code, BasePage could be an interface instead.如果没有共享的实现代码,BasePage 可以是一个interface
By convention, some name starting with I :按照惯例,一些名称以I开头:

public interface IPage
{
   SomeType SomePropertyB { get; set; }
   void SomeMethodA();
}
public class Page1 : IPage
{
  public SomeType SomePropertyB
  {
    get => ...;
    set => ...;
  }
  public void SomeMethodA()
  {
    ...
  }

  // Putting a page into a variable that could be either page.
  IPage page = new Page1();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM