简体   繁体   English

C#表单-控制在线程操作过程中丢失停靠状态

[英]C# form - controls losing dock state during threaded operation

I have a form with a menu strip, a status strip, and a main split container (which itself contains other split containers, tree views, tab control, etc). 我有一个带有菜单栏,状态栏和主拆分容器的表单(它本身包含其他拆分容器,树视图,选项卡控件等)。 Occasionally (fairly frequently, actually), the application will stop resizing controls within the main form (usually during or right after a background thread operation to retrieve data). 偶尔(实际上,很经常),应用程序将停止调整主窗体中控件的大小(通常在后台线程操作期间或之后立即检索数据)。 The control itself still claims its DockStyle is Fill, but the control isn't resizing with the form. 该控件本身仍然声明其DockStyle为Fill,但是该控件未调整表单的大小。 I can't find any information on what might cause this issue, has anyone come across anything like this before? 我找不到任何可能导致此问题的信息,以前有人遇到过这种情况吗?

Making sure you manipulate the UI from the proper thread is critical. 确保从适当的线程操作UI是至关重要的。 I recommend using the following extension methdds 我建议使用以下扩展方法

public delegate void EmptyHandler();
public delegate void ParamHandler(params object[] args);

public static void SafeCall(this Control control, 
                      ParamHandler method, params object[] args)
{
    if (control.InvokeRequired)
    {
        control.Invoke(method, args);
    }
    else
    {
        method(args);
    }
}
public static void SafeCall(this Control control, EmptyHandler method)
{
    if (control.InvokeRequired)
    {
        control.Invoke(method);
    }
    else
    {
        method();
    }
}

then you can call the appropriate method from the incorrect thread like this 那么您可以像这样从错误的线程中调用适当的方法

{  ... background thread 

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        this.SafeCall(SetImage, e.Result);
    }

 }

which calls the method SetImage(Bitmap bitmap) with the proper thread. 它使用适当的线程调用方法SetImage(Bitmap bitmap)

Well, that was stupid. 好吧,那太愚蠢了。

Turns out I had a rogue SuspendLayout() call that didn't have a corresponding ResumeLayout() call. 原来我有一个流氓SuspendLayout()调用,但没有相应的ResumeLayout()调用。 This behaviour isn't what I would have expected. 这种行为不是我所期望的。 Learn something new every day! 每天学些新东西! Thanks for looking! 感谢您的光临!

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

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