2010-11-19 6 views
1

Form1에 하나의 pictureBox를 만들고 InitialState라는 클래스의 인스턴스를 만드는 프로그램이 있습니다. InitialState는 소스가 Image에 표시되도록 표시하고, Timer를 사용한 시간이 지나면 다음 클래스 인 MainMenuState를 만듭니다. 자, 내가 만든 MainMenuState 클래스에서, 나는 다른 pictureBox를 만들고 그 Form1에 표시되도록하고 싶습니다. 나중에, 그 안에있는 그림을 조금 바꾸고 그 그림 상자를 (아마도) 파괴하려고합니다. 그 후, 프로그램은 다음 상태 (또 다른 클래스에 있음)로 들어가고, 다시 원래의 폼에 그림 상자를 추가하는 클래스를 원합니다.다른 클래스의 폼에 컨트롤 추가

기본적으로 컨트롤을 기본 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 
     }

초기 상태 (Initial) 클래스 :

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 클래스 :

,691 여기

내 코드입니다
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가 만들어지지 않습니다. 문제는, 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

이유를 발견했다 , 그리고 대의원에 의해 만들어진 두 번째는 뒤에 를 보여 줬어! 나는 그것을 앞에 가져올 필요가있다!

감사합니다. 그럼에도 불구하고, 나는 아마 당신 없이는 그렇게하지 않았을 것입니다.

편집 : 그러나 그 컨트롤을 앞으로 가져 오는 방법을 묻는 질문이 있습니까? a.BringToFront() 함수가 작동하지 않는 것 같습니다.

관련 문제