2014-04-20 2 views
0

양식에 사용자 정의 컨트롤을 표시하려고합니다. usercontrol은 새의 gif 이미지가있는 그림 상자입니다.양식에 Usercontrol이 표시됩니다.

//main form 
class Form1 
{ 
    //play button 
    private void gameButton1_Click(object sender, EventArgs e) 
    { 
     startPanel.Visible = false; 
     Game g = new Game(this.gamePanel1); 
     g.Start(); 
    } 
} 

class Game 
{ 
    //is set to true after starting game 

    public Game(gamePanel Display) 
    { 
     this.Display = Display; 
    } 

    bool Running = false; 

    public gamePanel Display; 

    public void Start() 
    { 

     Thread create_BirdsThread = new Thread(new ThreadStart(create_Birds)); 
     create_BirdsThread.Start(); 
     Running = true; 

    } 

    private void create_Birds() 
    { 
     while (Running) 
     { 

      //Display is a variable from class 'GamePanel' 
      Display.CreateBirds(); 
      Display.Refresh(); 

      //this is just to test that one bird works 
      Running = false; 
     } 
    } 
} 


class gamePanel : UserControl 
{ 
    public void CreateBirds() 
    { 
     yBird y = new yBird(); 
      y.BackColor = System.Drawing.Color.Transparent; 
      y.Location = new System.Drawing.Point(32, 56); 
      y.Size = new System.Drawing.Size(96, 65); 
      y.TabIndex = 1; 

      if (this.InvokeRequired) 
      { 
       this.BeginInvoke((MethodInvoker)delegate() 
       { 
        this.Controls.Add(y); 
       }); 
      } 
      else 
      { 
       this.Controls.Add(y); 
      } 
      y.Visible = true; 
      y.BringToFront(); 
    } 
} 

을하지만 내 화면에 새를 표시하지 않습니다

내가 이렇게 노력하고 있어요. 이 문제를 해결하는 방법은 무엇입니까?

감사합니다.

* 편집 :

내가 내 주요 형태와 Game.Start() 메소드

+0

if (this.InvokeRequired) { this.BeginInvoke((MethodInvoker)delegate() { this.Controls.Add(y); }); } 

은 당신이 불렀다이 변경? 또한 어떤 종류의 programm, WinForms, WPF ASP, XNA .....를 작성하는지 명확히하기 위해 질문에 태그를 추가하십시오. – TaW

+0

@TaW : 편집 참조 – JoJo

+0

yBird 클래스도 표시 할 수 있습니까? –

답변

0

나는 이미 고칠 수 있습니다.

난 그냥`Form.Load` 이벤트`create_Birds()`어디서나 같은이

if (this.InvokeRequired) 
      { 
       this.Invoke(new MethodInvoker(this.yellow)); 

      } 
2

물론의 코드를 추가,이 코드가 작동하지 않을 수 있습니다. Control.Begin/Invoke()가 작동하려면 .NET에서 먼저 코드를 실행해야하는 특정 스레드를 알아야합니다. Handle 속성에서 알 수 있습니다. 어떤 특정 스레드가 창을 소유하고 있는지 알려주고 기본 winapi 호출은 GetWindowThreadProcessId()입니다.

하지만 그건 당신의 코드에서 닭고기와 달걀 문제입니다. 코드가 Controls.Add() 메서드를 호출 할 때까지 기본 창이 만들어지지 않습니다. 어느 은 프로그램의 UI 스레드 (Form 객체를 소유하는 스레드)에서 실행되어야합니다. Windows는 자식 창을 다른 스레드가 소유하도록 허용하지 않습니다.

따라서 어떤 스레드로 호출해야하는지 알 수 없습니다. 핸들을 강제로 생성하면 소유권 규칙 때문에 프로그램이 다른 방식으로 종료됩니다.

큰 문제에주의하십시오. 나노초가 걸리는 코드를 실행하는 스레드를 만들고 있습니다. 이 속성 할당은 매우 저렴합니다. 실제 작업은 창을 만드는 데 많은 마이크로 초가 걸립니다. UI 스레드에서 실행할 필요가있는 요소 (및 필요). 따라서 스레드를 전혀 사용하지 않아도 아무런 이점이 없으므로 UI ​​스레드는 속성 설정시 몇 나노초를 낭비하지 않을 것입니다.

그래서 스레드를 완전히 제거하여 처리하십시오. 이미지를로드하는 것과 같이 느린 작업을 수행하는 경우 은 작업자 스레드에서 쉽게 수행 할 수 있습니다.

+0

감사합니다! 하지만 이것은 단지 시험 일뿐입니다. 내가 정말로 이루고자하는 것은 게임이 끝날 때까지 새를 만들어내는 것입니다. 그게 내가 스레드가 필요한 이유입니다. 이것이 작동하면'Running = false'을 제거하여 계속 진행합니다. – JoJo

+0

비트 맵은 작업 스레드에서 동시에 액세스 할 수없는 한 만들 수 있습니다.따라서 스레드의 백 버퍼를 그려 UI 스레드에 표시하는 시나리오가 효과적 일 수 있습니다. 이것은 지금까지 얻은 것과는 거리가 멀었습니다. 질문을 닫으십시오. –

관련 문제