6

我最近一直在研究 Android,并尝试将其功能之一移植到 C# 紧凑框架。

我所做的是创建一个抽象类,我称之为 Activity。这个类看起来像这样

  internal abstract class Activity
  {
      protected Form myForm;
      private static Activity myCurrentActivity = null;
      private static Activity myNextActivity = null;

      internal static void LoadNext(Activity nextActivity)
      {
         myNextActivity = nextActivity;
         if (myNextActivity != null)
         {
            myNextActivity.Show();
            if (myCurrentActivity != null)
            {
               myCurrentActivity.Close();
               myCurrentActivity = null;
            }
            myCurrentActivity = myNextActivity;
            myNextActivity = null;
         }
      }

      internal void Show()
      {
        //PROBLEM IS HERE
         Application.Run(myForm);
         //myForm.Show();
         //myForm.ShowDialog();
        //
      }

      internal void Close()
      {
         myForm.Close();
      }


      internal void GenerateForm()
      {
      ///Code that uses the Layout class to create a form, and then stores it in myForm
      //then attaches click handlers on all the clickable controls in the form
      //it is besides the point in this problem
      }

      protected abstract void Click(Control control);
      //this receives all the click events from all the controls in the form
      //it is besides the point in this problem

   }

我遇到的问题是运行Show()命令的一部分

基本上我所有的类都实现了上面的类,加载一个xml文件并显示出来。当我想转换到一个新的类/表单时(例如从 ACMain 到 ACLogIn)我使用这个代码

Activity.LoadNext(new ACLogIn);

应该加载下一个表单,显示它,然后卸载当前表单

我已经尝试过这些解决方案(在Show()方法中),这是每个解决方案的问题

  1. using myForm.ShowDialog()
    This works, but blocks execution, 这意味着旧表单不会关闭,并且我在表单之间移动的越多,进程堆栈增加的越多

  2. using myForm.Show()
    This works,在显示旧表单后关闭旧表单,但在此之后立即关闭程序并终止它

  3. 使用Application.Run(myForm)
    这仅适用于加载的第一个表单,当我移动到下一个表单时,它会显示它然后抛出一个异常,说“值不在预期范围内”

有人可以帮我解决这个问题或找到替代方案吗?

4

2 回答 2

5

如果您真的在为此导航创建自己的框架之后,您需要重新思考。传入的 Form 实例Application.Run永远不能关闭 - 当它关闭时,Application.Run 完成执行并且(通常)您的static void Main入口点退出并且应用程序终止。

我建议您将 Activity 更改为 UserControl:

public abstract class Activity : UserControl
{
  .... 
}

或作曲

public abstract class Activity
{
    private UserControl m_control;
  .... 
}

然后,不是关闭和显示表单,而是将主表单内的所有活动作为容器的父级。

As fair warning, this is going to get complex when you start wanting to show things in a Tab motif instead of a Stack, or having split views. Frameworks seem simple to create, but they're not so I'd at least consider using something already done unless you have compelling reasons to want to roll your own.

于 2012-10-24T13:23:06.457 回答
1

Application.Run通常与带Form参数的重载一起使用。这将是负责启动/显示其他表单的“主要”表单。这种“主要”形式可能是“隐藏的”。但是,我觉得这有点尴尬。

或者,您不需要主窗体,您可以使用Application.Run()启动消息泵来处理 Windows 消息;但是,线程正忙于处理消息并且无法显示对话框(它们必须显示在正在运行的线程中Application.Run)。您可以通过在调用之前Application.Run创建一个或多个表单对象来解决此问题,这些表单对象可以创建一个Timer对象,该对象将调用Form.Show()Form.ShowDialog()Timer.Tick事件处理程序上,以便在调用Run. 我觉得这也有点尴尬。

这两种解决方案都规避了您使用 Windows 和 WinForms 的方式;因此,我认为您需要考虑重新设计此应用程序以使用 Windows 和 .NET 的工作方式。

于 2012-10-24T13:06:43.193 回答