2011-06-28 14 views
2

私は私のフォームにロードしているElementHostsの束を持っています。この場合、要素ホストはすべて黒い背景で表示されます。別のコントロールを前面に持ってきて、もう一方のコントロールを閉じると、ElementHostは正常に再描画されます。いくつかのグーグルの後、私は彼らが上の表示されるように要素のホストあたり約300ミリ秒を取り、IサブクラスElementHostは、コンストラクタでこれを行うと、場合ElementHostレイアウトの問題

using (CreateGraphics()) { } 

ElementHostsは、すべての良いバックグラウンドで描画されていることがわかった....しかし、フォーム...そしてそれらは順番に表示されます...フォームを見ているように見えるのです...私はもちろんSuspendLayoutとResumeLayoutを手動で呼び出しましたが、これは結果を変更しません。

これはWindowsフォームの統合バグですか?それとも、コントロールを適切かつ合理的なレートで表示するためにこれについて何かできることはありますか?

ありがとうございました。

UPDATE:私は非常に簡単なコードの問題を再現することができる午前:

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

答えて

2

神聖な* * t、私はついにそれを働かせました。私は(ソースのカップルがあった.... How do I suspend painting for a control and its children? ... 1を名前に)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(); 
    } 

それは私の問題を解決し、黒の背景を台無しにして私を残していませんでした。 ..BUT私はresumeメソッドに以下を追加しようとする考え:

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

とBAM!できます。

+0

あなたはあなたのコントロールの中でそれを隠して再度表示するのではなく、 "Refresh"を呼び出してみましたか? –

+0

動作しません。 – Jeff

+1

@Jeff:同じ問題をサイズ変更する方法はありますか? http://stackoverflow.com/questions/29277844/elementhost-flickers-black-borders-on-resize/私はそれに絶望的です。 –

0

あなたの問題への直接の回答されていないが、あなただけの1 ElementHost(したがって、一つだけWPFを追加しようとしましたUserControl)をWindowsフォームに追加します。

個々のWPF UserControlを集約したWPF UserControlを作成すると、これを実現できます。 これは実行可能なソリューションですか? tは低下する可能性があります またはWindowsフォームコントロールとwpfものを混在させる必要がありますか?

+0

上記の例を試して、i <10をi <1に置き換えると、動作しないことがわかりますが、ElementHost内に乱れたボディが生成されます。 – Jeff

+0

2番目の質問については、それ自体は、私はWPFにWindowsフォームから私たちのアプリケーションを移行しようとしていると一貫したルックアンドフィールを維持したい。 – Jeff