【问题标题】:Trying to close a form after the next one is shown in C# cf在 C# cf 中显示下一个表单后尝试关闭表单
【发布时间】:2012-10-14 12:16:56
【问题描述】:

我最近一直在研究 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. 使用myForm.ShowDialog()
    这可行,但会阻止执行,这意味着旧表单不会关闭,并且我在表单之间移动的次数越多,进程堆栈增加的越多

  2. 使用myForm.Show()
    这可行,在显示旧表单后关闭旧表单,但之后立即关闭程序并终止它

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

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

【问题讨论】:

  • 主要问题是您只能拥有 1 个主表单。查看 Aplication 是否具有可写 MainForm 属性,然后将其与 Show() 一起使用。

标签: c# winforms compact-framework


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    我建议您将 Activity 更改为 UserControl:

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

    或作曲

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

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

    作为公平的警告,当您开始希望以 Tab 主题而不是 Stack 或拆分视图来显示内容时,这将变得复杂。创建框架似乎很简单,但实际上并非如此,除非您有令人信服的理由想要自己动手,否则我至少会考虑使用已经完成的东西。

    【讨论】:

    • 朋友的这个想法,其实很厉害,没想到让我觉得很傻,其实可能比我在关闭下一个表单之前打开一个新表单的想法要好
    • 我已经对我的项目进行了所有必要的更改,以融入您的想法我现在只显示一个表单并添加一个面板(我使用面板)而不是一个表单(因为我说我使用的是紧凑的框架,所以这里的情况有点奇怪)添加它后我删除了旧的,它运行良好,进程堆栈总是空的,而且加载时间减少了一半。再次感谢一百万。现在我怎么能给你无数颗星星?嗯,我会弄清楚的(:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 2011-02-14
    • 1970-01-01
    相关资源
    最近更新 更多