简体   繁体   English

不在UI线程上时的CreateParams

[英]CreateParams when not on UI thread

I am trying to prevent the flickering when loading forms. 我正在尝试防止在加载表格时出现闪烁。 I am loading a form through a new thread and then invoke back to UI. 我正在通过新线程加载表单,然后调用回UI。 But since I am creating the form on the non UI thread, the override (CreateParams) is not working as intended. 但是由于我是在非UI线程上创建表单的,所以重写(CreateParams)不能按预期工作。 Works flawlessly when I create it on the UI thread. 当我在UI线程上创建它时,它可以完美地工作。 How can I make it that it overrides when its back on the UI thread? 如何使其在返回到UI线程时被覆盖?

// How the loading is done, from UI thread
Thread GetPage = new Thread(() => LoadPage<T>(panel));

public static void LoadPage<T>(Panel Panel)
{ 
  Form form = Activator.CreateInstance(typeof(T)) as Form;

  // Now invoke to UI
   Panel.Invoke((MethodInvoker)delegate
   {
       form.TopLevel = false;
       form.AutoScroll = true;
       Panel.Controls.Add(form);
       form.Show();
   }
}

// Example of a form

public partial class Start : Form
{
    protected override CreateParams CreateParams { get { CreateParams cp =     
             base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } }

    public Start()
    {
    }
 }

It ought to be little obvious that it doesn't have anything to do with threading, considering that you are properly invoking to the UI thread. 考虑到您正确调用了UI线程,它与线程没有任何关系应该不太明显。 The value that CreateParams returns does in fact only get used when the native window is created. 实际上,仅当创建本机窗口时才使用CreateParams返回的值。 Which happens at the Controls.Add() call, which runs on the UI thread. 这发生在Controls.Add()调用上,该调用在UI线程上运行。 Nothing wrong with that aspect of the code. 代码的这一方面没有错。 And required, you'll crash the program if you try to set the parent of a window created on the wrong thread. 而且,如果您尝试设置在错误线程上创建的窗口的父级,则将使程序崩溃。

The real problem is the WS_EX_COMPOSITED style flag you are using. 真正的问题是您使用的WS_EX_COMPOSITED样式标志。 Compositing is only supported for top-level windows. 仅顶级窗口支持合成。 The Form class in Winforms. Winforms中的Form类。 But you defeated it by setting the TopLevel property to false . 但是您通过将TopLevel属性设置为false击败了它。 The style flag simply stops having an effect, there's no alternative for this for a client window. 样式标记只是停止起作用,对于客户端窗口而言,别无选择。 You'll need to move it to the parent Form that contains this child window. 您需要将其移动到包含此子窗口的父窗体。

Don't do this. 不要这样 WinForms controls must be created on the thread on which they'll be used, and they must be used from the thread that created them (the only exceptions being InvokeRequired , Invoke , BeginInvoke and EndInvoke ). WinForms控件必须在将使用它们的线程上创建,并且必须从创建它们的线程中使用(唯一的例外是InvokeRequiredInvokeBeginInvokeEndInvoke )。 Failure to follow these basic rules will result in failures. 不遵守这些基本规则将导致失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM