C#表单不接受用户输入(冻结行为)

时间:2016-02-17 23:07:43

标签: c# winforms

我最近在一个项目的控制台应用程序中使用Forms。我在新线程中启动并刷新我的窗口,如下所示:

public void runGame()
{
  Thread windowthread = new Thread(windowRender);
  threadRunning = true;
  windowthread.Start();
}

public void windowRender()
{
  if(!windowOpened)
  {
     window.gamewindow.Show(); //window.gamewindow is a typical Windows Form
     window.gamewindow.Refresh();
  }
  while (threadRunning)
  {
    if(shouldRender)
    {
      window.gamewindow.Refresh();
      shouldRender = false;
    }
  }
}

但是,当我启动表单(window.gamewindow,一个典型的Windows表单)时,它不接受用户输入,我甚至无法点击最大化,最小化和退出按钮,它不能拖着屏幕。它能够成功渲染和刷新(如图所示)。有谁知道为什么会这样,我能做些什么来解决它? Screenshot of working render

2 个答案:

答案 0 :(得分:3)

没有好的Minimal, Complete, and Verifiable example,我们无法确定问题是什么。但最有可能的是,您只是在主持窗口的线程中未能调用Application.Run()

您只是在标志shouldRender设置为true时更新窗口,但是它不提供处理用户输入的机制,也不提供由于控件之外的情况重绘窗口及其元素(例如,在被其他窗口部分或完全遮挡之后重新显示窗口等)。

如果要在新线程中托管窗口,则应该执行以下操作:

public void runGame()
{
    Thread windowthread = new Thread(windowRender);

    // STA threads are required for Winforms components!
    windowthread.SetApartmentState(ApartmentState.STA);

    threadRunning = true;
    windowthread.Start();
}

public void windowRender()
{
    // The Run() method will return with the gamewindow Form
    // is closed. You should notify the windowing system of a need
    // to redraw the Form by calling Invalidate() on it.
    Application.Run(window.gamewindow);
}

最有可能的是,您根本不需要threadRunningshouldRender标记。

答案 1 :(得分:0)

我猜你是通过不调用Application.DoEvents()来阻止Windows消息的。 将其插入while块之间,我猜它会帮助。