6

I've been studying Android lately and I tried to port one of its functions to C# compact framework.

What I did is create an Abstract class that I call Activity. This class looks like this

  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

   }

The problem I have is with running the part of the Show() command

Basically all my classes implement the above class, load an xml file and display it. When I want to transition to a new class/form (for example going from ACMain to ACLogIn) I use this code

Activity.LoadNext(new ACLogIn);

Which is supposed to load the next form, show it , and unload the current form

I have tried these solutions (in the Show() method) and here is the problem with each one

  1. using myForm.ShowDialog()
    This works, but blocks execution, which means that the old form does not close, and the more I move between the forms the more the process stack increases

  2. using myForm.Show()
    This works, closes the old form after the old one is shown, but immediately after that closes the program and terminates it

  3. using Application.Run(myForm)
    This works only on the first form loaded, when I move to the next form, it shows it then throws an exception saying "Value does not fall within the expected range"

Can someone help me fix this or find an alternative?

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;
  .... 
}

次に、フォームを閉じて表示する代わりに、メイン フォーム内のすべてのアクティビティをコンテナーとして親にします。

公正な警告として、スタックではなくタブモチーフで物事を表示したり、ビューを分割したりすると、これは複雑になります。フレームワークは簡単に作成できるように見えますが、そうではないので、独自のフレームワークを作成するやむを得ない理由がない限り、少なくとも既に作成されているものを使用することを検討します。

于 2012-10-24T13:23:06.457 に答える
1

Application.Run通常、Formパラメーターを受け取るオーバーロードと共に使用されます。これは、他のフォームの開始/表示を担当する「メイン」フォームになります。この「メイン」フォームは「非表示」にすることができます。でも、それはちょっともったいないと思います。

または、メイン フォームは必要ありませんApplication.Run()。メッセージ ポンプを起動して Windows メッセージを処理するために使用できます。ただし、スレッドはメッセージの処理でビジーであり、ダイアログを表示できません (実行中のスレッドに表示する必要がありますApplication.Run)。を呼び出す前に1 つまたは複数のフォーム オブジェクトを作成することで、これを回避Application.Runできます。これらのフォーム オブジェクトは、イベント ハンドラでまたはTimerを呼び出すオブジェクトを作成し、 の呼び出し後にフォームが表示されるようにすることができます。これもちょっとむずかしいと思います。Form.Show()Form.ShowDialog()Timer.TickRun

これらのソリューションはどちらも、Windows と WinForms を使用することが期待される方法を回避するものです。したがって、Windows と .NET が動作する方法で動作するように、このアプリケーションを再設計することを考える必要があると思います。

于 2012-10-24T13:06:43.193 に答える