web-dev-qa-db-ja.com

WPFデータグリッドのパフォーマンス

WPF Toolkitデータグリッドを使用していますが、現在、スクロールが非常に遅くなっています。グリッドには84列と805行があります。 (3つの固定列を含み、ヘッダーは固定されています。)水平および垂直の両方のスクロールは非常に遅いです。仮想化がオンになっていて、xamlで列の仮想化と行の仮想化を明示的に有効にしました。バインディングメソッドや、各セルテンプレートに含まれるxamlなど、パフォーマンスに実際に影響を与える可能性があることに注意する必要があるものはありますか?

注意すべき点の1つは、データグリッドの作成時に列を動的に追加していることです。それは何かに影響を及ぼしているでしょうか? (また、バインディングが正しく設定されるように、同時に動的にセルテンプレートを作成します。)

以下は、生成されるほとんどのセルのテンプレートからのコードです。基本的に、動的に追加する必要のある列(ほとんどの列)について、リストをループし、AddColumnメソッドを使用して列を追加します。さらに、バインディングステートメントがコレクション内の適切なアイテムに適切にインデックスを付けるようにテンプレートを動的に構築しますその列のために。テンプレートは複雑すぎず、2つのTextBlockだけですが、それぞれに4つの異なるプロパティをバインドしています。バインディングをOneWayに変更することで、パフォーマンスをもう少し絞り出すことができたようです。

 private void AddColumn(string s, int index)
    {
        DataGridTemplateColumn column = new DataGridTemplateColumn();
        column.Header = s;
        //Set template for inner cell's two rectangles
        column.CellTemplate = CreateFactViewModelTemplate(index);
        //Set Style for header, ie rotate 90 degrees
        column.HeaderStyle = (Style)dgMatrix.Resources["HeaderRotateStyle"];
        column.Width = DataGridLength.Auto;
        dgMatrix.Columns.Add(column);
    }


    //this method builds the template for each column in order to properly bind the rectangles to their color
    private static DataTemplate CreateFactViewModelTemplate(int index)
    {
        string xamlTemplateFormat =
            @"<DataTemplate xmlns=""http://schemas.Microsoft.com/winfx/2006/xaml/presentation""
            xmlns:x=""http://schemas.Microsoft.com/winfx/2006/xaml"">
            <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column=""0"" MinHeight=""10"" MinWidth=""10"" HorizontalAlignment=""Stretch"" Padding=""3 1 3 1"" TextAlignment=""Center"" Foreground=""{Binding Path=FactViewModels[~Index~].LeftForeColor,Mode=OneWay}"" Background=""{Binding Path=FactViewModels[~Index~].LeftColor,Mode=OneWay}"" Text=""{Binding Path=FactViewModels[~Index~].LeftScore,Mode=OneWay}"" />
            <TextBlock Grid.Column=""1"" MinHeight=""10"" MinWidth=""10"" HorizontalAlignment=""Stretch"" Padding=""3 1 3 1"" TextAlignment=""Center"" Foreground=""{Binding Path=FactViewModels[~Index~].RightForeColor,Mode=OneWay}"" Background=""{Binding Path=FactViewModels[~Index~].RightColor,Mode=OneWay}"" Text=""{Binding Path=FactViewModels[~Index~].RightScore,Mode=OneWay}"" />
            </Grid>
            </DataTemplate>";




        string xamlTemplate = xamlTemplateFormat.Replace("~Index~", index.ToString());

        return (DataTemplate)XamlReader.Parse(xamlTemplate);
    }
31
ctrlalt313373

私はあなたのソースコードを見ることができないので、あなたを助けるのはかなり難しいです。特に、WPFアプリケーションのパフォーマンスは多くの影響を受けるためです。注意すべき点に関するヒントについては、 WPFアプリケーションのパフォーマンスの最適化 を参照してください。そしてはい-各セルでどのxamlを使用するかは非常に重要です。通常、パフォーマンスの問題は「要素が多すぎる」ということになります。 TextBoxが30個の個別の要素だと思うことをご存知ですか? WPFのパフォーマンスプロファイリングツール を使用して、特定の問題の詳細を確認することをお勧めします。使用している要素の量を最小限に抑えるようにしてください(たとえば、必要に応じてTextBoxからTextBlockに切り替えます)。

また、アプリケーションを試してみるPCにパフォーマンスの問題が存在するかどうかを確認する必要があります。おそらく、使用しているPCがWPFをソフトウェアベースのレンダリングに強制しているのでしょう。または、BitmapEffectsを使用していますか?

編集:
コードを見て、変更することをお勧めします

column.Width = DataGridLength.Auto;

データグリッドは、何かが変更されるたびに(行の追加やスクロールなど)幅を動的に再計算する必要がないため、適切な固定幅に設定します。

20
Tobias Hertkorn

DataGridのパフォーマンスの問題に関する一般的なヒント:ウィンドウのサイズ変更、列の並べ替えなどを行った後、文字通り数秒で更新され、ウィンドウのUIがロックされている(1000行、5列)と、DataGridに問題がありました。 )。

それは、WPFサイズ計算の問題(バグ?)に帰着しました。 RowDefinition Height = "Auto"のグリッドに配置したため、レンダリングシステムは、おそらくグリッド全体を埋めることによって、すべての列と行のサイズを測定することにより、実行時にDataGridのサイズを再計算しようとしました(私が理解しているように)。これはどういうわけかこれをインテリジェントに処理することになっていますが、この場合はそうではありませんでした。

これが関連する問題であるかどうかを確認する簡単なチェックは、DataGridのHeightプロパティとWidthプロパティをテスト期間中の固定サイズに設定し、もう一度実行してみることです。パフォーマンスが回復した場合、恒久的な修正が次のオプションの中にある可能性があります。

  • 含まれる要素のサイズを相対(*)または固定値に変更します
  • DataGridのMaxHeightとMaxWidthを、通常の使用で取得できる値よりも大きい固定値に設定します
  • 別のサイズ変更戦略(Grid、DockPanelなど)で別のコンテナータイプを試す
11
TripleAntigen

私のプロジェクトの1つで、次のグリッドスタイル設定が大きなパフォーマンスの問題を引き起こしていました。

 <Style  TargetType='{x:Type controls:DataGrid}'>
    <Setter Property='ScrollViewer.CanContentScroll' Value='False' />
    ...

ScrollViewer.CanContentScroll設定を削除すると、パフォーマンスの問題はなくなりました。

2

基になるオブジェクトにセッターのみのプロパティがある場合がありました。同じプロパティにアクセスするには、コレクションにITypedListを実装し、個々のオブジェクトにTypeDescriptionProvider/ICustomTypeDescriptorを使用します。プロパティを削除するか、ゲッターを追加することで、パフォーマンスの問題が解決しました。

1

万が一、(USBまたはタブレットPCを介して)何らかの種類のタブレットをインストールしていますか

タブレットを使用すると、WPFデータグリッドにパフォーマンスのバグが見つかりました。私はビデオを投稿しました、そしてそれはMSによって認められます ここでこのスレッドで

乾杯、ジョン

1
Jon Kragh

このようなシナリオで提案することの1つは、スタイルを適用した方法と各セルのスタイルを確認することです。複雑なビジュアルツリーがある場合に適用されるスタイルは、パフォーマンスを低下させる傾向があります。

また、最新のWPF Datagridで遅延スクロールオプションを試すこともできます。

1
Vibes