ElementHost的布局问题 [英] ElementHost Layout Problems

查看:308
本文介绍了ElementHost的布局问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堆ElementHosts说我装上我的形式。发生这种情况时,该元件的主机都出现一个黑色背景。如果我把另一个控制前,然后关闭其他的控制,在ElementHosts通常粉刷一新。一些google搜索后,我发现,如果我子类的ElementHost并为此在构造

 使用(的createGraphics()){}
 

在ElementHosts都绘制好的背景....但是,他们需要约300ms的每个元素主机出现在窗体上......他们相继出现......因此它喜欢看的形式越来越奠定了..我有,当然称为SuspendLayout和ResumeLayout手动,但这并不改变结果

这只是Windows窗体的整合bugginess?或者是有什么我可以做这使控件显示正确,并以合理的速度?

感谢。

更新:我能够用非常简单的code重现该问题:

 公共部分类TestControl2:用户控件
    {
        公共TestControl2()
        {
            的InitializeComponent();
        }

    保护覆盖无效的OnLoad(EventArgs的发送)
    {
        base.OnLoad(E);

        //推迟负荷BackgroundWorker的似乎是这里涉及到的问题...
        VAR体重=新的BackgroundWorker();
        bw.DoWork + =委托{Thread.sleep代码(2000); };
        bw.RunWorkerCompleted + =委托
        {
            INT X = 0;
            INT Y = 0;
            的for(int i = 0;我小于20;我++)
            {
                无功控制=新面板();
                control.Width = 200;
                control.Height = 80;
                control.Controls.Add(新的ElementHost {儿童=新System.Windows.Controls.Label {内容= @你好},码头= DockStyle.Left,大小=新System.Drawing.Size(75,23)});
                control.Controls.Add(新的ElementHost {儿童=新System.Windows.Controls.Button {内容= @按钮},码头= DockStyle.Fill});
                VAR UC2 =新用户控件();
                uc2.Controls.Add(控制);
                control.Dock = DockStyle.Fill;
                uc2.Left = X;
                uc2.Top = Y;
                X + = control.Width + 10;
                //使用(uc2.CreateGraphics()){}解决了这个问题,但是减慢负载,所以它看起来像每个用户控件被添加一次加
                panel1.Controls.Add(UC2);
            }
        };

        bw.RunWorkerAsync();
    }
    }
 

解决方案

圣奔忙,我终于得到了它的工作。我试图从谷歌这个code(有一对夫妇的来源.... <一href="http://stackoverflow.com/questions/487661/how-do-i-suspend-painting-for-a-control-and-its-children">How做我暂停画一个控件及其子 ...命名一个):

 私人const int的WM_SETREDRAW = 0x000B;

    公共静态无效挂起(该控制的控制)
    {
        消息msgSuspendUpdate = Message.Create(control.Handle,WM_SETREDRAW,IntPtr.Zero,
            IntPtr.Zero);

        NativeWindow的窗口= NativeWindow.FromHandle(control.Handle);
        window.DefWndProc(REF msgSuspendUpdate);
    }

    公共静态无效简历(该控制的控制)
    {
        VAR WPARAM =新的IntPtr(1);
        消息msgResumeUpdate = Message.Create(control.Handle,WM_SETREDRAW,WPARAM,
            IntPtr.Zero);

        NativeWindow的窗口= NativeWindow.FromHandle(control.Handle);
        window.DefWndProc(REF msgResumeUpdate);

        control.Invalidate();
    }
 

这并没有解决我的问题,给我留下了黑色搞砸背景......但我想尝试加入以下的恢复方法:

 公共静态无效简历(该控制的控制)
      {
            control.Visible = FALSE;
            //上述现有code ....
            control.Visible =真;
      }
 

和BAM!它的工作原理。

I have a bunch of ElementHosts that I'm loading onto my form. When this happens, the element hosts all appear with a black background. If I bring another control to front, then close the other control, the ElementHosts are repainted normally. After some googling, I found that if I sub-class ElementHost and do this in the constructor

 using (CreateGraphics()) { }

The ElementHosts are all drawn with good backgrounds....BUT, they take about 300ms per element host to appear on the form...and they appear sequentially...so it's like watching the form getting laid out... I have, of course called SuspendLayout and ResumeLayout manually, but this doesn't change the result.

Is this just Windows Forms integration bugginess? Or is there something I can do about this to make the controls appear correctly and at a reasonable rate?

Thanks.

UPDATE: I am able to reproduce the problem with the very simple code:

    public partial class TestControl2 : UserControl
    {
        public TestControl2()
        {
            InitializeComponent();
        }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        // deferring load with the BackgroundWorker seems to be related to the problem here...
        var bw = new BackgroundWorker();
        bw.DoWork += delegate { Thread.Sleep(2000); };
        bw.RunWorkerCompleted += delegate
        {
            int x = 0;
            int y = 0;
            for (int i = 0; i < 20; i++)
            {
                var control = new Panel();
                control.Width = 200;
                control.Height = 80;
                control.Controls.Add(new ElementHost { Child = new System.Windows.Controls.Label { Content = @"Hello" }, Dock = DockStyle.Left, Size = new System.Drawing.Size(75, 23) });
                control.Controls.Add(new ElementHost { Child = new System.Windows.Controls.Button { Content = @"button" }, Dock = DockStyle.Fill });
                var uc2 = new UserControl();
                uc2.Controls.Add(control);
                control.Dock = DockStyle.Fill;
                uc2.Left = x;
                uc2.Top = y;
                x += control.Width + 10;
                // adding using (uc2.CreateGraphics()) {} fixes the problem but slows down the load so it looks like each UserControl is being added one at a time
                panel1.Controls.Add(uc2);
            }
        };

        bw.RunWorkerAsync();
    }
    }

解决方案

Holy sh*t, I finally got it working. I tried this code from Google (there were a couple of sources.... How do I suspend painting for a control and its children? ...to name one):

    private const int WM_SETREDRAW = 0x000B;

    public static void Suspend(this Control control)
    {
        Message msgSuspendUpdate = Message.Create(control.Handle, WM_SETREDRAW, IntPtr.Zero,
            IntPtr.Zero);

        NativeWindow window = NativeWindow.FromHandle(control.Handle);
        window.DefWndProc(ref msgSuspendUpdate);
    }

    public static void Resume(this Control control)
    {
        var wparam = new IntPtr(1);
        Message msgResumeUpdate = Message.Create(control.Handle, WM_SETREDRAW, wparam,
            IntPtr.Zero);

        NativeWindow window = NativeWindow.FromHandle(control.Handle);
        window.DefWndProc(ref msgResumeUpdate);

        control.Invalidate();
    }

It didn't solve my problem and left me with the black messed up backgrounds...BUT I thought to try adding the following to the Resume method:

      public static void Resume(this Control control)
      {
            control.Visible = false;                
            // existing code above....
            control.Visible = true;
      }

and BAM!!! it works.

这篇关于ElementHost的布局问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆