25

CodePlexの WPF DataGrid を使用しており、仮想化をグループ化で使用する必要があります。

この質問はトピックに関するもので、 MSDN の例を指していますが、単純な (つまり、単一の「列」) DataTemplates を使用した ListControls のみを対象としています。

グループ化と仮想化は、グリッドのかなり一般的な使用例のようです。これを実現する標準/推奨/簡単な方法はありますか?

4

4 に答える 4

38

ここでのパーティーに遅れていることに気づきました...しかし、最近この問題に遭遇しました(.NET 4に組み込まれたDataGridを使用しています)。残念ながら、DataGrid で Grouping が使用されると、行の仮想化はまだ行われません。

GroupItem のテンプレートのエキスパンダー内で ItemsPresenter を使用していて、デフォルトではエキスパンダーが展開されていないと仮定すると、デフォルトの BooleanToVisibilityConverter を使用して、ItemsPresenter の可視性を Expander の IsEnabled プロパティに単純にバインドしてみてください。

<BooleanToVisibilityConverter x:Key="bool2vis" />


<DataGrid.GroupStyle>
    <GroupStyle>
        <GroupStyle.ContainerStyle>
            <Style TargetType="{x:Type GroupItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type GroupItem}">
                            <Expander x:Name="exp">
                                <ItemsPresenter Visibility="{Binding ElementName=exp, Path=IsExpanded, Converter={StaticResource bool2vis}}" />
                            </Expander>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </GroupStyle.ContainerStyle>
    </GroupStyle>
</DataGrid.GroupStyle>

DataGrid の読み込みに非常に時間がかかるという問題が発生している場合 (折りたたまれたエキスパンダーにあるにもかかわらず、データグリッド内のすべてのレコードを本質的に描画しているため)... 上記のコードを使用すると、データグリッドが描画されなくなります。グループを展開するまでレコードを表示し、その後、その特定のグループのレコードのみを引き出します。

欠点は、エキスパンダーがデフォルトで折りたたまれていて、それでも行が仮想化されない場合にのみ役立つことです (展開されたグループに 100 個のアイテムがあり、20 個しか画面に収まらない場合、100 個すべてが最初に描画されます)。グループを展開した時間)。

利点は、基本的に DataGrid レコードの遅延読み込みを実装しているため、実際にアイテムを表示する必要がある (グループを展開することを選択する) まで描画作業を実行しないことです。私の製品では、グループ ヘッダーに、グループ内のすべてのアイテムに対して操作を実行するためのボタンが組み込まれていたため、グループ内の個々のアイテムに対して操作を実行する必要がない限り、ユーザーがグループを展開することはほとんどありませんでした。

*このトリックを使用する場合に注意すべきことの 1 つは、列ヘッダーに明示的な幅または最小幅を設定する必要があることです (DataGrid が最初に読み込まれたときに項目が描画されないため、列ヘッダーは最大サイズに合わせて自動サイズ変更できません)。アイテム)。

真の仮想化が将来のサービス パックで実装されることを願っていますが、実装されていない場合は、これが誰かの助けになることを願っています!

アップデート

この問題は、新しい添付プロパティVirtualizingPanel.IsVirtualizingWhenGroupingを使用して .NET 4.5 で修正されるようです。

于 2011-02-17T16:30:34.080 に答える
2

ListView または DataGrid でグループ化が有効になっているときに UI 仮想化を有効にできる組み込み機能はありません。DataGrid が存在しないアイテムをグループ化する方法。グループ化を適用するには、コントロールはコレクション全体をロードする必要があり、仮想化の目的全体が無効になります。おそらくできる最善の方法は、現在必要なデータと、存在するデータ量に関するある種の一般的なデータのみを提供してから偽造するという点で、ビューモデル(再度バインドするオブジェクト)に何らかの仮想化を提供することです景色を自分で。

グループ化を使用すると、次のようになります。グループ化が最初に有効になると、すべてのグループが折りたたまれます。したがって、ビューモデルは、存在するグループごとに 1 つのアイテムのみを提供する必要があります。ビューに既存のすべてのグループが含まれていることを確認するだけです。ユーザーが 1 つのグループを展開するとすぐに、ViewModel はそのグループのアイテムを動的に補充します。これは仮想化の非常にシンプルで基本的な方法であり、最適ではありませんが、開始点としては適切かもしれません。アプローチを説明するだけです。

于 2009-10-03T06:47:10.330 に答える