前回MTG Blog: ◆RIAサービスを使ってデータ表示(VS2012)の続き。
<データの表示をカスタマイズする>
カスタムクエリを追加するには
- RIA1.Webプロジェクトの「MyService.cs」を開き、以下の「GetEmployeesInLongon」メソッドを追加する。
- public IQueryable<Employees> GetEmployeesInLondon()
- {
- return this.ObjectContext.Employees.Where(e => e.City == "London");
- }
- ビルド
- RIA1プロジェクトの「EmployeeList.xaml.cs」を開き「GetEmployeesQuery」メソッドを今作成した「GetEmployeesInLondonQuery」メソッドに置き換える。
- public EmployeeList()
- {
- InitializeComponent();
- this.dataGrid1.ItemsSource = _MyContext.Employees;
- //_MyContext.Load(_MyContext.GetEmployeesQuery());
- _MyContext.Load(_MyContext.GetEmployeesInLondonQuery());
- }
- これで実行して「EmployeeList」を開くと以下のように「London」のみのデータが表示される。
「DomainDataSource」コントロールを使ってデータをロードする
これまではコードビハインドへのコーディング追加によって、「Employee」テーブルの内容をロードしていたが、「DomainDataSource」なるコントロールを使ってXAMLのみでデータをロードする方法が用意されている。(GUIでクエリーデータソースをドラッグアンドドロップなどして自動生成させるとVisualStudioはこいつを使うようである)
「DomainDataSource」を使ったデータ読み込みの方法を試してみる。
- RIA1プロジェクトの「EmployeeList.xaml.cs」を開きデータロードのロジックをコメントアウト。
- public EmployeeList()
- {
- InitializeComponent();
- //this.dataGrid1.ItemsSource = _MyContext.Employees;
- //_MyContext.Load(_MyContext.GetEmployeesQuery());
- //_MyContext.Load(_MyContext.GetEmployeesInLondonQuery());
- }
- RIA1プロジェクトの「EmployeeList.xaml」を開き、ツールボックスからデザインビューの「DataGrid」のすぐ上に「DomainDataSource」コントロールをドラッグする。
(「DomainDataSource」自体はユーザーに何かしらを表示するコントロールではないのでデザイナー画面には表示されない。その昔、コンポーネントなどと呼ばれていた類のコントロール) - 「DomainDataSource」のプロパティを以下のように設定し、「GetEmployeesQuery」によってデータを自動的に取得させる。
- <riaControls:DomainDataSource Name="employeeDataSource" QueryName="GetEmployeesQuery" AutoLoad="True" >
- <riaControls:DomainDataSource.DomainContext>
- <ds:MyContext/>
- </riaControls:DomainDataSource.DomainContext>
- 「DataGrid」の「ItemsSource」に「DomainDataSource」コントロールの「Data」プロパティをバインディングする。
- <sdk:DataGrid AutoGenerateColumns="True" IsReadOnly="True" x:Name="dataGrid1" MinHeight="100" ItemsSource="{Binding Data, ElementName=employeeDataSource}" />
「DomainDataSource」に手動で読み込む
「DomainDataSource」には「AutoLoad」を「False」にして手動で読み込む方法も用意されているので、それを使ってみる。
- 「DomainDataSource」の「AutoLoad」を「False」にする。
- 「TextBlock」の次にデータロード用のボタンを追加する。
「DomainDataSource」コントロールには予め「LoadCommand」が用意されているようなので、それを「Command」にバインドしてあげれば良さそうだ。
- <Button Width="100" HorizontalAlignment="Left" Content="Load" Command="{Binding LoadCommand, ElementName=employeeDataSource}"/>
「DomainDataSource」に抽出条件を指定する
「DomainDataSource」に画面から抽出条件を指定して表示できるようにする。
- 「RIA1.Web」プロジェクトの「MyService.cs」に以下の抽出メソッドを追加する。
- public IQueryable<Employees> GetEmployeesByCity(string cityname)
- {
- return this.ObjectContext.Employees.Where(e => e.City == cityname);
- }
- 「RIA1」プロジェクトの「EmployeeList.xaml」のLoadボタンをStackPanelに入れ、抽出条件指定用のTextBlockを追加する。
- <StackPanel Orientation="Horizontal">
- <TextBlock Text="CityName : " />
- <TextBox Name="txtCity" Width="100" Height="20"/>
- <Button Width="100" HorizontalAlignment="Left" Content="Load" Command="{Binding LoadCommand, ElementName=employeeDataSource}"/>
- </StackPanel>
- 「DomainDataSource」コントロールに「QueryParameters」プロパティを追加し、上記の抽出条件指定用TextBlockとバインドする。
- <riaControls:DomainDataSource Name="employeeDataSource" QueryName="GetEmployeesByCityQuery" AutoLoad="False" >
- <riaControls:DomainDataSource.DomainContext>
- <ds:MyContext/>
- </riaControls:DomainDataSource.DomainContext>
- <riaControls:DomainDataSource.QueryParameters>
- <riaControls:Parameter ParameterName="cityname" Value="{Binding Text, ElementName=txtCity}"/>
- </riaControls:DomainDataSource.QueryParameters>
- </riaControls:DomainDataSource>
- これで実行し、抽出条件に「London」と入力して「Load」ボタンを押すと「London」のデータだけが表示される。
「DomainDataSource」にソート条件を指定する
- 「DomainDataSource」には「SortDescriptors」属性を指定することによって簡単にソート条件を追加することができる。
- <riaControls:DomainDataSource Name="employeeDataSource" QueryName="GetEmployeesByCityQuery" AutoLoad="False" >
- <riaControls:DomainDataSource.DomainContext>
- <ds:MyContext/>
- </riaControls:DomainDataSource.DomainContext>
- <riaControls:DomainDataSource.QueryParameters>
- <riaControls:Parameter ParameterName="cityname" Value="{Binding Text, ElementName=txtCity}"/>
- </riaControls:DomainDataSource.QueryParameters>
- <riaControls:DomainDataSource.SortDescriptors>
- <riaControls:SortDescriptor PropertyPath="LastName" Direction="Ascending" />
- </riaControls:DomainDataSource.SortDescriptors>
- </riaControls:DomainDataSource>
- ソート指定した項目は先頭カラムに表示される。
「DomainDataSource」にページング処理を追加する
- 「DomainDataSource」のクエリーを「GetEmployeesQuery」に戻して、追加した「QueryParameters」を削除する。
- ツールボックスから「DataGrid」の下に「DataPager」コントロールをドロップし、XAMLを以下のように指定する。
- <sdk:DataPager Source="{Binding Data, ElementName=employeeDataSource}" PageSize="4" HorizontalAlignment="Left"/>
- これで実行して「EmployeeList」を表示させると4行ごとにページングされて表示されるのが判る。
「DomainDataSource」にフィルターを追加する
「DomainDataSource」に抽出条件を指定する、ではサーバーに対して抽出処理をやり直したが、今度はクライアント側だけでフィルター処理を行う。
- 「DomainDataSource」に以下のように「FilterDescriptors」属性を追加する。
- <riaControls:DomainDataSource.FilterDescriptors>
- <riaControls:FilterDescriptor
- PropertyPath="City"
- Operator="IsEqualTo"
- IgnoredValue=""
- Value="{Binding ElementName=txtCity, Path=Text}" >
- </riaControls:FilterDescriptor>
- </riaControls:DomainDataSource.FilterDescriptors>
- 実行して「EmployeeList」を表示させる。
- 「CityName」テキストボックスにフィルター対象の「City」を指定して「Load」ボタンを押すとフィルターされたデータが表示される。
<マスタ詳細ビューを作る>
「EmployeeList」の一覧表示ができたので、次は一覧で選択したデータを詳細表示してみる。詳細表示には「Silverlith Toolkit」に含まれている「DataForm」コントロールを使用する。
「DataForm」コントロールの使い方は以下に簡単に纏めている。
MTG Blog: ◆DataFormコントロールを使ってみる
DataFormを追加するには
- 「RIA1」プロジェクトから「EmployeeList.xaml」を開く
- 「DataForm」用の名前空間を追加する
- xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
- 「DataPager」コントロールの下に以下のXAMLを追加して「DataForm」コントロールを追加する。
1: <dataForm:DataForm x:Name="dataForm1" Header="Employee Infomation"
2: AutoGenerateFields="True" HorizontalAlignment="Left"
3: AutoEdit="False" AutoCommit="True" Height="400" Width="800"
4: CurrentItem="{Binding SelectedItem,ElementName=dataGrid1}"
5: Margin="0,12,0,0" />
- アプリケーションを実行し「EmployeeList」を表示したのちに一覧でデータを選択すると、その下の「DataForm」に詳細が表示される。
<関連データを表示する>
OrderとOrder_Detailsテーブルを使って親子関係(集約)のあるデータを表示してみる。
関連テーブルのデータを表示するには
- 「RIA1」プロジェクトの「Views」フォルダーを右クリックして「追加」「新しい項目」をクリックする。
- 「Orders」という名前で「Silverlight」ページを追加する。
- 「Orders.xaml」を開く。
- <Grid>タグの間に以下のXAMLを追加する。
- <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource PageScrollViewerStyle}" >
- <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">
- <TextBlock Text="Orders" Style="{StaticResource HeaderTextStyle}"/>
- </StackPanel>
- </ScrollViewer>
- 「MainPage.xaml」を開く。
- 「EmployeeList」のリンクの次に「Orders」ページへのリンクを追加する。
- <HyperlinkButton x:Name="Link5" Style="{StaticResource LinkStyle}" NavigateUri="/Orders" TargetName="ContentFrame" Content="Orders"/>
- <Rectangle x:Name="Divider4" Style="{StaticResource DividerStyle}"/>
- 「RIA1.Web」プロジェクトの「MyService.metadata.cs」を開く。
- 「OrdersMetadata」クラスの「Order_Details」プロパティに「Include」属性と「Composition」属性を追加する。
(この属性により、Order_Detailsのコレクションもインスタンシングされるのかな) - 「RIA1.Web」プロジェクトの「MyService.cs」を開く。
- 「GetOrders」メソッドを修正して、項番8のコレクションを作る元ネタ用に、関連する「Order_Details」も読み込む指定に変更する。
- public IQueryable<Orders> GetOrders()
- {
- //return this.ObjectContext.Orders;
- return this.ObjectContext.Orders.Include("Order_Details").OrderBy(p => p.OrderID);
- }
- 「Orders.xaml」を開く。
- 「データ」メニューの「データソースの表示」をクリックして「データソースウィンドウ」を開く。
- 「Orders」をデザイン画面にドラッグする。
「Orders」の列を含む「DataGrid」が表示される。 - 同様に、「Orders」のノードの中に含まれる「Order_Details」を「Orders」の「DataGrid」の下にドラッグする。
「Order_Details」の列を含む「DataGrid」が表示される。 - 追加された「DataGrid」の「Width」プロパティを削除し、画面の幅いっぱいに表示されるようにする。
- それぞれの「DataGrid」の前に「TextBlock」コントロールを追加して以下のようにラベルが表示されるようにする。
- 「DomainDataSource」にフィルターを追加して取得されるデータ数を制限しておく。
1: <riaControls:DomainDataSource.FilterDescriptors>
2: <riaControls:FilterDescriptor PropertyPath="EmployeeID" Operator="IsLessThan" Value="5" />
3: </riaControls:DomainDataSource.FilterDescriptors>
- アプリケーションを実行し、「Orders」を開く。
- 「Order見出し」の行を選択すると対応する明細データが「Order明細」に表示される。
関連テーブルのデータを表示するには2
上記では「データソース」をドロップすることによって半自動的に画面デザインを行ったが、実装を確認する意味で中身を確認しながら手動で設定してみる。
- 「RIA1」プロジェクトの「Views」フォルダーを右クリックして「追加」「新しい項目」をクリックする。
- 「注文」という名前で「Silverlight」ページを追加する。
- 「注文.xaml」を開く。
- <Grid>タグの間に以下のXAMLを追加する。
1: <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">
2:
3: <TextBlock Text="注文" Style="{StaticResource HeaderTextStyle}"/>
4: </StackPanel>
- 「MainPage.xaml」を開く。
- 「EmployeeList」のリンクの次に「注文」ページへのリンクを追加する。
1: <HyperlinkButton x:Name="Link4" Style="{StaticResource LinkStyle}" NavigateUri="/注文" TargetName="ContentFrame" Content="注文"/>
2:
3: <Rectangle x:Name="Divider3" Style="{StaticResource DividerStyle}"/>
- 「注文.xaml」を開き「注文」タイトルの下に「注文タイトル」の「TextBlock」を追加
1: <TextBlock Text="注文タイトル" />
- その下に「DtaGrid」を追加し、以下のように設定。
1: <sdk:DataGrid x:Name="注文DataGrid" AutoGenerateColumns="True" ItemsSource="{Binding Data,ElementName=注文DomainDataSource}" Height="200" IsReadOnly="True"/>
- その下に「注文明細」の「TextBlock」を追加
1: <TextBlock Text="注文明細" />
- その下に「DataGrid」を追加し、以下のように設定。
1: <sdk:DataGrid x:Name="注文明細DataGrid" AutoGenerateColumns="True" ItemsSource="{Binding Data.Order_Details, ElementName=注文DomainDataSource}" Height="200" />
- これで実行して、「注文」ページを表示させると「Orders」ページとほぼ同様の表示となる。
0 件のコメント:
コメントを投稿