フォーム上で .NET コントロールをダブルバッファリングするにはどうすればよいですか?
-
09-06-2019 - |
質問
保護されたものを設定するにはどうすればよいですか DoubleBuffered
フォーム上のコントロールのプロパティでちらつきが発生していますか?
解決
これはより一般的なバージョンです ダミーの解決策.
リフレクションを使用して保護されたものにアクセスできます ダブルバッファリング プロパティを選択し、次のように設定できます。 真実.
注記:あなたがすべき 開発者税を支払ってください そしてそうではありません ユーザーがターミナル サービス セッションで実行している場合は、ダブル バッファリングを使用します。 (例えば。リモート デスクトップ) このヘルパー メソッドは、ユーザーがリモート デスクトップで実行している場合、ダブル バッファリングを有効にしません。
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);
イアン ターミナル サーバーでのこれの使用に関する詳細情報が記載されています。
public void EnableDoubleBuffering()
{
this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,
true);
this.UpdateStyles();
}
1 つの方法は、ダブル バッファリングする特定のコントロールを拡張し、コントロールの ctor 内に DoubleBuffered プロパティを設定することです。
例えば:
class Foo : Panel
{
public Foo() { DoubleBuffered = true; }
}
ノブグズ 彼のリンクにメソッドのクレジットが記載されているので、再投稿するだけです。このオーバーライドをフォームに追加します。
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
これは私にとっては最もうまくいきました。Windows 7 では、コントロールの多いフォームのサイズを変更すると、大きな黒いブロックが表示されていました。代わりにコントロールがバウンスするようになりました。しかし、その方が良いです。
拡張方法 コントロールのダブルバッファリングをオンまたはオフにします
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);
ダブルバッファリングを試す前に、SuspendLayout()/ResumeLayout() で問題が解決するかどうかを確認してください。
これにより、私は 多く 追跡するまで、サードパーティ製のコントロールで 2 日間悲しみに暮れました。
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 設定を設定するだけで、ここにリストされているすべてのプロパティが自動的に設定されることがわかりました。