84

私は実際にこれを解決しましたが、後世のために投稿しています。

デュアル モニター システムの DataGridView で非常に奇妙な問題が発生しました。この問題は、コントロールの再描画が非常に遅い (完全な再描画の場合は 30 秒など) として現れますが、画面の 1 つにある場合のみです。一方、再描画速度は問題ありません。

最新の非ベータ ドライバー (175 など) を搭載した Nvidia 8800 GT を使用しています。ドライバーのバグですか?私はこの特定の構成で生活しなければならないので、それは空中に置いておきます。(ただし、ATI カードでは発生しません...)

描画速度はセルの内容とは関係がなく、カスタム描画を行ってもパフォーマンスはまったく向上しません。塗りつぶされた四角形を描画する場合でも同様です。

後で、ElementHost (System.Windows.Forms.Integration 名前空間から) をフォームに配置すると問題が解決することがわかりました。いじる必要はありません。DataGridView もオンになっているフォームの子である必要があります。Visibleプロパティが true である限り、サイズを (0, 0) に変更できます。

アプリケーションに .NET 3/3.5 依存関係を明示的に追加したくありません。リフレクションを使用して、(可能であれば) 実行時にこのコントロールを作成するメソッドを作成します。それは機能し、少なくとも、必要なライブラリを持たないマシンでは正常に失敗します-単に遅くなるだけです.

このメソッドを使用すると、アプリの実行中に修正を適用することもできるため、(Spy++ を使用して) フォームで WPF ライブラリがどのように変更されているかを簡単に確認できます。

試行錯誤を繰り返した結果、(フォームだけではなく) コントロール自体でダブル バッファリングを有効にすると、問題が解決することがわかりました。


そのため、DoubleBuffering を有効にできるように、DataGridView に基づいてカスタム クラスを作成するだけで済みます。それでおしまい!

class CustomDataGridView: DataGridView
{
    public CustomDataGridView()
    {
        DoubleBuffered = true;
    }
}

グリッドのすべてのインスタンスがこのカスタム バージョンを使用している限り、すべて問題ありません。これが原因でサブクラス ソリューションを使用できない状況に遭遇した場合 (コードがない場合)、そのコントロールをフォームに挿入しようとすることができると思います :) (リフレクションを使用して DoubleBuffered プロパティを外部から強制的にオンにして、依存関係をもう一度回避しようとする可能性が高くなります)。

そんな些細なことで、こんなにも多くの時間を奪われてしまうのは悲しいことです...

4

9 に答える 9

66

DoubleBufferingを有効にできるように、DataGridViewに基づいてカスタムクラスを作成する必要があります。それでおしまい!


class CustomDataGridView: DataGridView
{
    public CustomDataGridView()
    {
        DoubleBuffered = true;
    } 
}

グリッドのすべてのインスタンスがこのカスタムバージョンを使用している限り、すべて問題ありません。これが原因でサブクラスソリューションを使用できない状況に遭遇した場合(コードがない場合)、そのコントロールをフォームに挿入しようと試みることができると思います:)(ただし、リフレクションを使用して、DoubleBufferedプロパティを外部から強制的にオンにして、依存関係をもう一度回避しようとする可能性が高くなります)。

こんなに些細なことが私の時間の多くを食い尽くしたのは悲しいことです...

注:質問を回答済みとしてマークできるように、回答を回答にする

于 2008-10-01T12:41:14.397 に答える
61

Benoit が提案するようにサブクラス化せずに、リフレクションを使用してプロパティを設定するコードを次に示します。

typeof(DataGridView).InvokeMember(
   "DoubleBuffered", 
   BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
   null, 
   myDataGridViewObject, 
   new object[] { true });
于 2009-10-01T19:49:51.043 に答える
20

VB.NETでそれを行う方法を探している人のために、コードは次のとおりです。

DataGridView1.GetType.InvokeMember("DoubleBuffered", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.SetProperty, Nothing, DataGridView1, New Object() {True})
于 2012-04-24T18:52:47.950 に答える
1

この問題を修正するために行ったことを追加するだけです。最新のNvidiaドライバーにアップグレードすると、問題が解決しました。コードを書き直す必要はありませんでした。

完全を期すために、カードは 2008 年 3 月 (v. 169) のドライバを搭載した Nvidia Quadro NVS 290 でした。最新 (2009 年 2 月付けの v. 182) にアップグレードすると、すべてのコントロール、特に DataGridView のペイント イベントが大幅に改善されました。

この問題は、(開発が行われる) ATI カードでは見られませんでした。

于 2009-02-26T22:35:41.230 に答える
1

一番!:

Private Declare Function SendMessage Lib "user32" _
  Alias "SendMessageA" _
  (ByVal hWnd As Integer, ByVal wMsg As Integer, _
  ByVal wParam As Integer, ByRef lParam As Object) _
  As Integer

Const WM_SETREDRAW As Integer = &HB

Public Sub SuspendControl(this As Control)
    SendMessage(this.Handle, WM_SETREDRAW, 0, 0)
End Sub

Public Sub ResumeControl(this As Control)
    RedrawControl(this, True)
End Sub

Public Sub RedrawControl(this As Control, refresh As Boolean)
    SendMessage(this.Handle, WM_SETREDRAW, 1, 0)
    If refresh Then
        this.Refresh()
    End If
End Sub
于 2014-06-10T16:54:18.120 に答える
1

問題の解決策を見つけました。詳細表示プロパティのトラブルシューティング タブに移動し、ハードウェア アクセラレーション スライダーを確認します。新しい会社の PC を IT から入手したとき、フルから 1 ティックに設定されており、データグリッドに問題はありませんでした。ビデオ カード ドライバを更新してフルに設定すると、データグリッド コントロールの描画が非常に遅くなりました。それで、元の場所にリセットしたところ、問題はなくなりました。

このトリックがうまくいくことを願っています。

于 2009-10-07T20:28:17.023 に答える
0

デュアル モニター システムで .NET 3.0 と DataGridView を使用すると、同様の問題が発生しました。

このアプリケーションでは、セルを変更できないことを示す灰色の背景でグリッドを表示します。「設定の変更」ボタンを選択すると、プログラムはセルの背景色を白に変更して、セルのテキストを変更できることをユーザーに示します。「キャンセル」ボタンは、前述のセルの背景色を灰色に戻します。

背景色が変わるとちらつきが発生し、同じ数の行と列を持つデフォルト サイズのグリッドの短い印象が生じます。この問題は、プライマリ モニターでのみ発生し (セカンダリ モニターでは発生しません)、シングル モニター システムでは発生しません。

上記の例を使用してコントロールをダブルバッファリングすると、問題が解決しました。大変お世話になりました。

于 2008-10-07T19:45:51.177 に答える