2010-11-19 20 views
1

Form1に1つのpictureBoxを作成し、InitialStateという名前のクラスのインスタンスを作成するプログラムがあります。 InitialStateは、ソースがイメージに表示されるようにソースを配置し、Timerを使用して、ある時間が経過した後、次のクラスMainMenuStateを作成します。さて、私が作成したMainMenuStateクラスでは、別のpictureBoxを作成し、そのForm1に表示させたいと思います。後で、その中の写真を少し変えて、そのpictureBoxを(おそらく)破壊したいと思います。その後、プログラムは次の状態(まだ別のクラスにあります)に入り、再びそのクラスが元のフォームにピクチャボックスを追加するようにします。別のクラスからフォームにコントロールを追加する

基本的に、私は、上記のフォームではなく、後で作成するクラスから、メインのForm1にコントロールを動的に追加したいと思います。私はこれを行う方法についてインターネット上で検索してきましたが、Form1クラスのControls.Addメソッドを呼び出すためには、代理人を使用する必要があるようです。私はそれを試み、コードがコンパイルされますが、pictureBoxはまだ表示されません。

ここに私のコードです:

Form1クラス:

 public const string RESOURCE_PATH = "C:/Users/Noel/Documents/Visual Studio 2010/Projects/A/Resources/Animations/"; 

public Form1() 
     { 
      InitializeComponent(); //here, the first pictureBox shows 

      iInitializeComponent(); 
      zacetnaAnimacija.Dock = DockStyle.Fill; //zacetnaAnimacija is the first pictureBox that appears 
      zacetnaAnimacija.Anchor = AnchorStyles.Top | AnchorStyles.Left; 
      zacetnaAnimacija.SizeMode = PictureBoxSizeMode.StretchImage; 
      InitialState intialState = new InitialState(this, zacetnaAnimacija); //entering InitialState 
     }

初期状態クラス:

class InitialState : State 
    { 

     System.Timers.Timer initialTimer; 
     PictureBox pictureBox1; 
     Form1 form; 

     public InitialState (Form1 form, PictureBox pictureBox1) { 
      this.form = form; 
      GifImage zacetnaSlika = new GifImage(Form1.RESOURCE_PATH + "Presenting.gif"); //this is just a .gif picture I'm displaying 

      Image trenutnaSlika = zacetnaSlika.GetFrame(0); //a method that plays the .gif 
      pictureBox1.Image = trenutnaSlika; //makes the first .gif display 
      this.pictureBox1 = pictureBox1;    

      initialTimer = new System.Timers.Timer(2500); 
      initialTimer.Enabled = true; 
      initialTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
     } 

     private void OnTimedEvent(object source, ElapsedEventArgs e) 
     { 
      initialTimer.Enabled = false; 
      MainMenuState menuState = new MainMenuState(form, pictureBox1); //enters main menu state with the Form1 argument passed on 

     }

MainMenuStateクラス:

class MainMenuState : State 
    { 
     Form1 form; 

     public MainMenuState (Form1 form, PictureBox pictureBox1) { 
      this.form = form; 
      GifImage zacetnaSlika = new GifImage(Form1.RESOURCE_PATH + "animated.gif"); 

      Image trenutnaSlika = zacetnaSlika.GetFrame(0); 
      pictureBox1.Image = trenutnaSlika; //this simply makes another .gif appear in the picture box instead of the first one 

      PictureBox a = new PictureBox(); //HERE'S my problem, when I want to add ANOTHER pictureBox to that form. 
      a.BackgroundImage = trenutnaSlika; 
      a.Location = new System.Drawing.Point(0, 0); 
      a.Name = "zacetnaAnimacija"; 
      a.Size = new System.Drawing.Size(150, 150); 
      a.TabIndex = 1; 
      a.TabStop = false; 

      AddControl(a); //calling the delegate 
     } 


     public delegate void AddControls(PictureBox a); 
     public void AddControl(PictureBox a) 
     { 
      if (form.InvokeRequired) 
      { 
       AddControls del = new AddControls(AddControl); 
       form.Invoke(del, new object[] { a }); 
      } 
      else 
      { 
       form.Controls.Add(a); 
      } 
     }

私が言ったように、コードはコンパイルされますが、MainMenuStateが作成されると、Form1にはPictureBox aが作成されません。私がMainMenuStateでデリゲートを使用せず、単にform.Controls.Add(a)のようなことをしようとすると、 "クロススレッド操作が有効ではありません"という例外が発生します。コンパイルすることさえできます。だから、私はデリゲートを使ったのですが、今でもそれは動作しません。

誰かお手伝いできますか?

+0

あなたのフルコードを表示することがあります。私はこれを実行し、それは正常に働いた... –

+0

さて、私は今完全なコードを入れました。 – NoelAramis

答えて

1
 initialTimer = new System.Timers.Timer(2500); 

これは、問題が発生している理由の一部です。 Elapsedイベントはスレッドプールスレッドで実行され、BeginInvokeの曲と踊りを強制的に実行します。代わりにSystem.Windows.Forms.Timerを使用し、TickイベントはUIスレッド上で実行されます。

また、メモリ管理に問題があります。これらのクラスはIDisposableを実装する必要があります。

+0

それは動作します!どうもありがとう!! – NoelAramis

0

代わりの

form.Invoke(del, new object[]{a}); 

試してみてください。これは、最初のPictureBoxは、フォーム全体をカバーしているためという事実は

form.Invoke(new ThreadStart(delegate 
    { 
     form.Controls.Add(a); 
    } 
)); 
+0

いいえ、以前と同じです。私は今完全なコードを入れました。おそらく、私はこのコードのより単純なバージョンを試したときに、うまくいきました。しかし、私はこれをどこで作っているのか分かりません。この正確なコードで間違い... – NoelAramis

1

ああ私の神は、私はちょうど

X_X

理由を見つけました代議員によって作成された2番目のものはの後ろに と表示されています。私はそれを前面に持っていく必要があります!

ありがとうございます、それでも、私はおそらくあなたなしでそれに来ていないでしょう。

編集:ただし、コントロールを前面に表示する方法を尋ねることはできますか? a.BringToFront()関数は動作していないようです。