2012-01-19 36 views
2

私は3つのパネルを持つフォームを持っています。上部のパネルにはリストボックス、中央のパネルにはグリッド、下部のパネルにはグリッドがあります。下のグリッドのスクリーンショットを撮る必要がありますが、グリッドにさらに多くの行があり、すべての行を表示するにはスクロールする必要があります。私はスクリーンショットを撮る前にフォームのサイズの下のグリッドを作成したいと思います。これを行うには、2つのトップパネルの.Visibleをfalseに設定します。私の問題は、フォームのサイズとしてグリッドを表示するために、フォームが再描画される前にスクリーンショットが取得されることです。スクリーンショットを取得するコードを実行する前に、フォームが再描画/再描画されたことをどうすれば保証できますか?Winformsペインティングは同期または非同期ですか?

私はスクリーンショットを撮るためにCapture screenshot of active window?のArsenMkrtの答えを使用しています。

EDIT:グリッドはInfragistics UltraGridです。

+0

@ハンスはあなたのコメントを回答し、私はそれを受け入れるでしょう。 Update()は完全に機能しました。 –

答えて

3

フォームのUpdate()メソッドを呼び出します。保留中の塗料があれば、それらが実行され、フォームが完全に描画されていることを確認できます。間違いなくここでは、パネルを隠すにはフォームをバックグラウンドで再描画する必要があります。

これは自分のフォームでのみ機能し、別のプロセスが所有するウィンドウでは機能しません。フォームのDrawToBitmap()メソッドを使用すると、通常は機能します(同期は必要ありません)。ただし、すべての子コントロールでサポートされているわけではありません。 RichTextBoxやWebBrowserなどのActiveXコントロールは、基になるWindowsメッセージを正しく実装していません。

0

Applicaton.DoEvents()を使用すると、すべてのウィンドウメッセージが処理され、呼び出しから返されたときにサイズ変更とペイントが完了します。その直後にフォームのスクリーンショットを撮ることができます。

+0

'DoEvents'は**絶対に**あなたが考慮する最後のものでなければなりません。まず、それは 'VB.NET'であり、' C# 'ではないので利用できません。第2に、VB/VB.NETでは再入可能性のために問題が発生するためです。第三に、99.999999999999999%の時間を費やすより良い方法があり、それを使うことに頼らなければならないということは、何か間違っていることを意味します。 –

+0

Application.DoEvents()は言語とは関係ありません。それはすべての.NET言語から利用可能です。 –

+0

OK。ありがとうございました - 私はC#にもその欠陥があることに気付いていませんでした。最初の拒否を削除し、2番目のVB/VB.NET参照を削除します。残りはまだ立っています。 :)私はdownvoteを削除しますが、おそらくその修正に基づいて急いでいたからです。他の2つの理由のため、私はそれをアップヴォートすることはできません。 –

1

Winforms DataGridを使用している場合は、そのような問題をすべて解決する必要はありません。そのまま使用するControl.DrawToBitmap()

var width = dataGridView1.Width; 
var height = dataGridView1.Height; 
var x = dataGridView1.Left; 
var y = dataGridView1.Top; 

var bitmap = new Bitmap(width, height); 
var targetBounds = new Rectangle(x, y, width, height); 
dataGridView1.DrawToBitmap(bitmap, targetBounds); 

bitmap.Save("C:\\DataGridView.bmp"); 
+0

また、Control.Refresh()... dataGridView1.Refresh()を試すと、コントロールとそのすべての子を即座に再描画します。これがスレッドセーフであるかどうかはわかりません。 –

関連する問題