これで、アプリケーションで最も注目する部分を作成する準備ができました。以下の要素を表示するためのカスタムセルを作成する ICellFactory オブジェクトを作成します。
これらすべての作業は、ICellFactory インターフェイスを実装するカスタム MusicCellFactory クラスによって実行されます。カスタムセルファクトリは、それをグリッドの CellFactory プロパティに割り当てるだけで使用できます。
MusicCellFactory クラスはデフォルトの CellFactory クラスから継承され、CreateCellContent メソッドをオーバーライドすることにより、各セルのコンテンツを表示するために使用する要素を作成します。
CreateCellContent メソッドは、パラメータとして、親グリッド、基本クラスによって作成されてセルの背景と境界を提供する Border 要素、および作成する必要があるセル(単一のセル、またはマージされている場合は複数のセル)を指定する CellRange オブジェクトを受け取ります。
CreateCellContent は、セルコンテンツのみを作成します。境界と背景も含めてセル全体を作成する場合は、代わりに CreateCell メソッドをオーバーライドします。
この例では、CreateCellContent メソッドは、通常のセルとグループ行内のセルという 2 つの主要なケースを処理します。
通常のセルの処理は簡単です。メソッドは、作成される列に基づいて新しい SongCell 要素または RatingCell 要素を返すだけです。これらは StackPanel から派生するカスタム要素で、セルが表すデータ項目に連結される画像とテキストを含みます。
グループ行のセルは、多少複雑です。このアプリケーションでは、グループ行はアーティストとアルバムを表すために使用されます。これらの項目は、ソースコレクションのデータ項目に対応していません。ここで使用する CreateCellContent メソッドは、フェイクの Song オブジェクトを作成してアーティストとアルバムを表します。このフェイクの Song オブジェクトには、グループに含まれる曲に基づいて計算されたプロパティが含まれます。アルバムの Duration は、アルバムの各曲の Duration の合計として計算され、Rating は、アルバムの各曲の Rating の平均として計算されます。このフェイクの Song オブジェクトが作成されると、SongCell 要素と RatingCell 要素を通常どおりに使用できます。
次に、MusicCellFactory クラスとその CreateCellContent の実装を多少簡略化して示します。
BindGroupRowCell メソッドは、前述のフェイクの Song オブジェクトを作成し、それらを行の DataItem プロパティに割り当てて CreateCellContent メソッドで使用できるようにし、グループ行の最初のセルに特別な処理を行います。各グループ行の最初のセルは他と異なり、通常のセルのコンテンツに加えてグループの折りたたみ/展開のボタンが含まれています。
次に、各グループ行の最初の項目を処理するコードを示します。
最後に、アーティストとアルバムを表す Song オブジェクトを作成するコードを示します。このメソッドでは、GroupRow.GetDataItems メソッドを使用して、グループに含まれるすべてのデータ項目のリストを取得します。次に、LINQ ステートメントを使用して、グループ内の曲の合計サイズ、再生時間、およびレーティングの平均を計算します。
これが必要な作業の大部分です。残っている部分は、個々のセルを表すために使用するカスタム要素の定義だけです。次の要素があります。
次の図に、グリッドにどのように要素が表示されるかを示します。
これらはすべて通常のWPF Framework の要素で、Microsoft Blend またはコードで作成できます。
次に、RatingCell 要素を実装するコードを示します。他の要素も同様で、サンプルソースコードを確認すれば実装の詳細がわかります。
RatingCell 要素は簡単です。これは、いくつかの Image 要素を含む StackPanel で構成されます。Image 要素の数は、表示するレーティング(コンストラクタに渡される値)によって定義されます。各 Image 要素によって 1 つの星アイコンが表示されます。これは、レーティングが変化しないことを前提とした静的な処理なので、動的な連結は必要ありません。