最大のキモ「フィールドテンプレート」
Dynamic Dataは簡単にデータ駆動アプリケーションができるほか、カスタマイズが容易にできる部分も魅力の1つです。カスタマイズは大別して2種類に分けられます(図3)。
- Dynamic Dataの動的ユーザーコントロールなど、プレゼンテーション部分のカスタマイズ(カスタム動的ユーザーコントロールの追加や差し替え、独自のテーブルページの追加など)
- メタデータに対する振る舞い部分など、DataAnnotations名前空間の属性を使用したカスタマイズ(入力値の制限や検証を実施)
プレゼンテーション部分のカスタマイズには、主にフィールドテンプレートを使用します。Dynamic Dataにおいて、フィールドテンプレートはエンティティのデータ(データモデル)を表示するユーザーコントロールです。Dynamic Dataは、実行時にメタデータから最適なフィールドテンプレートを推論し、データを表示する要素を動的に変更します。フィールドテンプレート自身は基本的に表示(名前.ascx)と編集(名前_Edit.ascx)が対で存在しているのも特徴です(表示部分は汎用的に利用できるため、編集しかないものもあります)。
新しい項目の追加から「動的データフィールド」を追加した場合、自動で編集用のフィールドテンプレートも追加されます。似たような言葉に「データフィールド」があり、これはフィールドテンプレートの列のことを指します(図4)。
なお、フィールドテンプレートは、データモデルの値やメタデータにアクセス可能なFieldTemplateUserControlクラスを継承して作られています。
プロジェクト作成時に用意されるDynamic Dataフィールドコントロールは次のとおりです。
動的データフィールドユーザーコントロール | 概要 |
Boolean.ascx | Boolean型のデータを表示するのに利用(チェックボックス) |
Boolean_Edit.ascx | 編集画面の時にBoolean型のデータを表示するのに利用(チェックボックス) |
Children.ascx | 一体多リレーションシップを持つデータをリレーションシップのあるページへとリダイレクトさせるのに利用(ハイパーリンク) |
Children_Insert.ascx | 親項目が未作成の時に子項目を表示するページに遷移させないために利用(コントロール使用せず) |
DateTime.ascx | 日付型のデータを表示するのに利用(リテラル) |
DateTime_Edit.ascx | 編集画面の時に日付型のデータを表示するのに利用(テキストボックス) |
Decimal_Edit.ascx | 編集画面の時にDecimal型のデータを表示するのに利用(テキストボックス) |
EmailAddress.ascx | Dynamic Dataでのみ使用できる特殊なデータ型「EmailAddress型」を表示するのに利用(ハイパーリンク) |
Enumeration.ascx | EnumDataTypeAttributeで定義された列挙型を表示するのに利用(リテラル) |
Enumeration_Edit.ascx | 編集画面の時に列挙型の値を持つデータを表示するのに利用(ドロップダウンリスト) |
ForeignKey.ascx | 外部キーを持つデータを表示するのに利用(ハイパーリンク) |
ForeignKey_Edit.ascx | 編集画面の時に外部キーを持つデータを表示するのに利用(ドロップダウンリスト) |
Integer_Edit.ascx | 編集画面の時にInteger型のデータを表示するのに利用(テキストボックス) |
ManyToMany.ascx | ADO.NET Entity Framework使用時に多対多のデータフィールド表示に利用(ハイパーリンク) |
ManyToMany_Edit.ascx | 編集画面の時に多対多のデータを表示するのに利用(チェックボックスリスト) |
MultilineText_Edit.ascx | 編集画面の時にテキストブロックを利用しているデータを表示するのに利用(テキストボックスのMultiLineモード) |
Text.ascx | String型、Decimal型、Double型、Int型、byte型、short型、long型のデータを表示するのに利用(リテラル) |
Text_Edit.ascx | 編集画面の時にString型、Decimal型、Double型、Int型、byte型、short型、long型のデータを表示するのに利用(テキストボックス) |
Url.ascx | Dynamic Dataでのみ使用できる特殊なデータ型「URL型」を表示するのに利用(ハイパーリンク) |
既存でも一定のフィールドテンプレートのコントロールがありますが、入力や編集方法を切り換えたい場合や、独自のフィールドテンプレートを作成したい場合もあると思います。このようなフィールドテンプレートのカスタマイズについては今後触れる予定なので、既定である程度の用意がされていること、スキャフォールディング機能がうまく動作してメタデータとマッピングしてくれていることを覚えておいてください。
Dynamic Dataによるフィルタ処理
Dynamic Dataは動的にデータの表示を行いますが、ページ内で特定の値をトリガーにしてフィルタをかけたいという要望もありました。それを実現するのがDynamicフィルタ機能です(図5)。
具体的には、Filtersフォルダに配置されるユーザーコントロールがそれにあたります。
フィルターユーザーコントロール | 概要 |
Boolean.ascx | Boolean型のチェックの有無でフィルタ |
Enumeration.ascx | 列挙型の値によるフィルタ |
ForeignKey.ascx | 一体多リレーションシップを持つデータに対するフィルタ |
動的フィルターコントロール自身は、ドロップダウンの値を表示するための処理を記載してあります。
Dynamic Dataによるフィルタ処理の内部の仕組みは、.NET 4で追加されたQueryExtenderコントロールとの連動により実現されています。QueryExtenderコントロールを一言で説明すると、「LinqDataSourceコントロールとEntityDataSourceコントロールで取得されたデータにフィルタをかけるコントロール」です。QueryExtenderコントロールの詳細は『サーバーサイドの開発改善に注目!~VS2010+ASP.NET 4新機能(後編)~』(CodeZine)を参照ください。
では、List.aspxページを例に、少し掘り下げてみましょう。
<asp:QueryExtender TargetControlID="GridDataSource" ID="GridQueryExtender" runat="server"> <asp:DynamicFilterExpression ControlID="FilterRepeater" /> </asp:QueryExtender>
QueryExtenderコントロールの設定はページに表示されているグリッド(GridDataSource)に対して、Dynamic Dataの指定された列の値を利用してフィルタ機能を実現するDynamicFilterコントロールを適用するDynamicFilterExpressionにFilterRepeaterを指定しています。それではフィルタ対象となる、ID、FilterRepeaterを見てみましょう。
<asp:QueryableFilterRepeater runat="server" ID="QueryableFilterRepeater1"> <ItemTemplate> <asp:Label ID="Label1" runat="server" Text='<%# Eval("DisplayName") %>' OnPreRender="Label_PreRender" /> <asp:DynamicFilter runat="server" ID="DynamicFilter" OnFilterChanged="DynamicFilter_FilterChanged" /><br /> </ItemTemplate> </asp:QueryableFilterRepeater>
ページ内に表示されるデータフィールドの中から、Boolean型、列挙型、一体多リレーションシップを持つデータがある場合に、その数だけ列名(DisplayName)のラベルと、ドロップダウンリストによる値(DynamicFilterコントロール)が表示されます。
後は、実行時にQueryExtenderコントロールがうまくフィルタ機能を実現してくれます。
シンプルにして強力。これがDynamicフィルタの基本です。フィルタ機能のカスタマイズのポイントとして独自のフィルターコントロールの作成が挙げられます。例えば、ある一定の数値以上(未満)のデータを取得したい場合、または、一定区間の値のデータを取得したい場合などです。詳細な方法は、今後紹介したいと思います。