ちらつきに苦しんでいるフォーム上のコントロールの保護されたDoubleBuffered
プロパティを設定するにはどうすればよいですか?
ダミーのソリューション のより一般的なバージョンを次に示します。
リフレクションを使用して、保護された DoubleBuffered プロパティを取得し、trueに設定できます。
注: 開発者税を支払う ではなく、 ユーザーがターミナルサービスセッション (例:リモートデスクトップ)このヘルパーメソッドは、ユーザーがリモートデスクトップで実行されている場合、ダブルバッファリングをオンにしません。
public static void SetDoubleBuffered(System.Windows.Forms.Control c)
{
//Taxes: Remote Desktop Connection and painting
//http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
if (System.Windows.Forms.SystemInformation.TerminalServerSession)
return;
System.Reflection.PropertyInfo aProp =
typeof(System.Windows.Forms.Control).GetProperty(
"DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(c, true, null);
}
チェック このスレッド
その答えの中核を繰り返して、ウィンドウでWS_EX_COMPOSITEDスタイルフラグをオンにして、フォームとそのすべてのコントロールの両方をダブルバッファリングすることができます。スタイルフラグはXP以降で使用可能です。ペイントが速くなるわけではありませんが、ウィンドウ全体がオフスクリーンバッファに描画され、一気に画面にブリットされます。目に見える絵画のアーティファクトなしで、ユーザーの目に即座に見えるようにします。それは完全に問題がないわけではなく、一部の視覚スタイルレンダラーは、特にタブが多すぎる場合のTabControlで不具合が発生する可能性があります。 YMMV。
このコードをフォームクラスに貼り付けます。
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
この手法とWinformのダブルバッファリングサポートの大きな違いは、Winformのバージョンは一度に1つのコントロールでのみ動作することです。個々のコントロールのペイント自体は引き続き表示されます。これは、特にペイントされていないコントロールの四角形とウィンドウの背景のコントラストがひどい場合、フリッカー効果のようにも見えます。
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control)
.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(ListView1, true, null);
Ian には、これをターミナルサーバーで使用することに関する詳細情報があります。
public void EnableDoubleBuffering()
{
this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,
true);
this.UpdateStyles();
}
1つの方法は、ダブルバッファリングする特定のコントロールを拡張し、コントロールのctor内でDoubleBufferedプロパティを設定することです。
例えば:
class Foo : Panel
{
public Foo() { DoubleBuffered = true; }
}
拡張メソッドコントロールのダブルバッファリングをオンまたはオフにする
public static class ControlExtentions
{
/// <summary>
/// Turn on or off control double buffering (Dirty hack!)
/// </summary>
/// <param name="control">Control to operate</param>
/// <param name="setting">true to turn on double buffering</param>
public static void MakeDoubleBuffered(this Control control, bool setting)
{
Type controlType = control.GetType();
PropertyInfo pi = controlType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(control, setting, null);
}
}
使用法(たとえば、DataGridViewをDoubleBufferedにする方法):
DataGridView _grid = new DataGridView();
// ...
_grid.MakeDoubleBuffered(true);
nobugz は彼のリンクのメソッドのクレジットを取得します。ただ再投稿しています。このオーバーライドをフォームに追加します。
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
これは私にとって最も効果的でした。Windows7では、コントロールの重いフォームのサイズを変更すると、大きな黒いブロックが表示されました。代わりにコントロールがバウンスします!しかし、それはましです。
ダブルバッファリングを試みる前に、SuspendLayout()/ ResumeLayout()が問題を解決するかどうかを確認してください。
これにより、追跡するまでサードパーティのコントロールで2日間lotの悲嘆を引き起こしました。
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
私は最近、他のいくつかのコントロールを含むコントロールのサイズを変更/再描画するときに多くの穴(ドロップ)がありました。
WS_EX_COMPOSITEDとWM_SETREDRAWを試しましたが、これを使用するまで何も機能しませんでした。
private void myPanel_SizeChanged(object sender, EventArgs e)
{
Application.DoEvents();
}
ただ渡したかっただけです。
この素晴らしいソリューションのvb.netバージョン....:
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H2000000
Return cp
End Get
End Property
コントロールを独自のクラスに継承し、そこにプロパティを設定することもできます。この方法は、すべてのコントロールで同じ設定をたくさん行う傾向がある場合にも便利です。
フォームのDoubleBuffered設定を設定するだけで、ここにリストされているすべてのプロパティが自動的に設定されることがわかりました。