2

フォームにロードしているElementHostsがたくさんあります。これが発生すると、要素ホストはすべて黒い背景で表示されます。別のコントロールを前面に移動してから他のコントロールを閉じると、ElementHostsは正常に再描画されます。グーグルした後、ElementHostをサブクラス化して、コンストラクターでこれを実行すると、

 using (CreateGraphics()) { }

ElementHostsはすべて良い背景で描かれています...しかし、フォームに表示されるのに要素ホストごとに約300msかかります...そしてそれらは順番に表示されます...フォームがレイア​​ウトされるのを見るようなものです...私はもちろん、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

なんてこった、ようやく機能しました。Google からこのコードを試してみました (いくつかのソースがありました....コントロールとその子の描画を一時停止するにはどうすればよいですか? ...名前を付けると):

    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 を 1 つだけ (つまり、WPF UserControl を 1 つだけ) WindowsForm に追加しようとしましたか。

個々の WPF UserControl をすべて集約する WPF UserControl を作成すると、これを実現できます。これはあなたにとって実行可能な解決策ですか?または、Windowsフォームコントロールとwpfフォームコントロールを混在させる必要がありますか?

于 2011-06-30T15:21:23.963 に答える