2

我有一堆要加载到表单中的 ElementHost。发生这种情况时,元素主机都显示为黑色背景。如果我将另一个控件放在前面,然后关闭另一个控件,则 ElementHosts 将正常重新绘制。经过一番谷歌搜索,我发现如果我将 ElementHost 子类化并在构造函数中执行此操作

 using (CreateGraphics()) { }

ElementHosts 都是用良好的背景绘制的……但是,每个元素主机大约需要 300 毫秒才能出现在表单上……而且它们是按顺序出现的……所以就像看着表单布局一样……我有,当然手动调用了 SuspendLayout 和 ResumeLayout,但这不会改变结果。

这只是 Windows 窗体集成错误吗?或者我可以做些什么来使控件以合理的速度正确显示?

谢谢。

更新:我可以用非常简单的代码重现问题:

    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();
    }
    }
4

2 回答 2

2

天哪,我终于让它工作了。我从谷歌尝试了这段代码(有几个来源......如何暂停控件及其子项的绘制? ......举个例子):

    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();
    }

它没有解决我的问题,给我留下了黑色混乱的背景......但我想尝试将以下内容添加到 Resume 方法中:

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

和砰!!!有用。

于 2011-06-30T20:17:28.300 回答
0

尽管不是您问题的直接答案,但您是否尝试将一个 ElementHost(因此只添加一个 WPF UserControl)添加到您的 WindowsForm。

如果您创建一个聚合所有单独的 WPF UserControl 的 WPF UserControl,您可能会实现此目的。这对您来说是一个可行的解决方案吗?t 可能会减少 或者您是否必须将 Windows 窗体控件与 wpf 控件混合使用?

于 2011-06-30T15:21:23.963 回答