WCF Data Servicesの新機能 – データバインド

WCF Data Servicesの新機能5)データバインドをご紹介します。(2/24に実施されたTechDaysセッションのフォローアップも兼ねています)

このシリーズの目次は以下になります。
1) WCF Data Servicesの新機能 – 射影
2) WCF Data Servicesの新機能 – カウント
3) WCF Data Servicesの新機能 – Server Driven Paging(SDP)
4) WCF Data Servicesの新機能 – Feed Customization
5) WCF Data Servicesの新機能 – データバインド
6) WCF Data Servicesの新機能 – カスタムプロバイダ1
7) WCF Data Servicesの新機能 – カスタムプロバイダ2
8) WCF Data Servicesの新機能 – リクエストパイプライン
9)Open Data Protocolの実装 – Share Point Server 2010のデータを操作する

 

また以下のトピックに関しては1)の記事を参照してください。
■名称の変更
■新バージョン
■更新モジュール(開発環境)

■データバインド
WPFでTwowayバインドを平易に実現することが可能になりました。
これには、DataServiceCollection<T>という追加されたクラスを使用します。

簡単に手順をご紹介します。

1.SQL Serverに対してDemoという名前でデータベースを作成します。このためのスクリプトをこちらに用意しました。

2.Demoデータベースにある2つのテーブルをそのままEDMでモデル化してDetaServicesで公開します。

EDMは以下のようになります。

image

またDataServicesのエンドポイントは以下のようになります。

image

3.上記のDataServiceに接続するWPFクライアントを作成します。

まずMainWindow.xamlです。

<Window x:Class="MyClientApp.MainWindow"     xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"     Title="商品カタログ" Height="277" Width="573" VerticalAlignment="Bottom" WindowStyle='ThreeDBorderWindow'>     <Grid>         <Grid.RowDefinitions>             <RowDefinition Height="35*" />             <RowDefinition Height="160*" />         </Grid.RowDefinitions>

        <TextBlock Text="WCF Data Services Bind Demo" Margin="5" FontSize="25" Background="#81FFFF00" FontFamily="MV Boli" FontWeight="Normal" FontStyle='Normal' TextAlignment='Center' />

        <StackPanel Orientation="Horizontal" Grid.Row="1">             <Grid Margin="0,0,0,0" Name="grid1" Width="200"  >                 <ListBox ItemsSource="{Binding}"                          Name="Products"                          IsSynchronizedWithCurrentItem="False">                     <ListBox.ItemTemplate>                         <DataTemplate>                             <TextBlock Text="{Binding Path=Name}"                                        FontSize="20"                                        FontWeight="Bold"/>                         </DataTemplate>                     </ListBox.ItemTemplate>                 </ListBox>             </Grid>

            <StackPanel Orientation="Vertical" Width="350">                 <TextBox Name="txtName"                          Text="{Binding ElementName=Products, Path=SelectedItem.Name, Mode=TwoWay}"                          FontSize="20" Height="35" Margin="5" />                 <TextBox Name="txtCost"                          Text="{Binding ElementName=Products, Path=SelectedItem.Cost, Mode=TwoWay}"                          FontSize="20"                          Height="35"                          Margin="5"/>                 <TextBox Name="txtCategory"                          Text="{Binding ElementName=Products, Path=SelectedItem.Categories.Name}"                          FontSize="20"                          Height="35"                          Margin="5" IsReadOnly="True" Background="#FFEC1E1E" Foreground="#FFC38484" />                 <StackPanel Orientation="Horizontal">                     <Button Name="btnReadData"                         Margin="5"                         FontSize="20"                         Height="35"                         Click="btnLoadData_Click"  Width="160">                         読み込み                     </Button>                     <Button Name="btnSaveChanges"                         Margin="5"                         FontSize="20"                         Height="35"                         Click="btnSaveChanges_Click" Width="160">                         保存                     </Button>                 </StackPanel>

            </StackPanel>          </StackPanel>     </Grid> </Window>

 

見た目は以下のような感じですね。
Visual Studio のデザイナです。(テーマが入っているので、ちょっと見た目に変化があります)image

コードの部分は以下の様になります。

public partial class MainWindow : Window {     DemoEntities ctx;

    public MainWindow()     {         InitializeComponent();         LoadData();     }

    private void LoadData()     {         ctx = new DemoEntities(            new Uri("https://localhost:18346/DemoService.svc/"));

        //DataServiceCollection<Products> products =         //   new DataServiceCollection<Products>         //       (from p in ctx.Products.Expand("Categories")         //        select p);         IEnumerable<Products> products =             from p in ctx.Products.Expand("Categories")             select p;

        this.grid1.DataContext = products;             }

    private void btnSaveChanges_Click(object sender, RoutedEventArgs e)     {         ctx.SaveChanges();         MessageBox.Show("保存しました");     }

    private void btnLoadData_Click(object sender, RoutedEventArgs e)     {         LoadData();     } }

4.後は実行して確認してみます。

下図のように「カニ缶づめ」を選択して「カニ缶づめ1」と変更した直後保存ボタンを押します。

image

するとどうなるでしょうか?
答えはデータベースには反映されません。読み込みボタンを押すと変更した”1”が消えて「カニ缶づめ」に戻っていることが分かります。

この理由は、ここまでのコードにはデータの取得として以下のコードが用いられていたからです。

IEnumerable<Products> products =             from p in ctx.Products.Expand("Categories")             select p;

これに対して下記のコードのコメントを復活させて、上記のコードをコメントにして実行してください。
DataServiceCollection<T>を使用した手法です。

//DataServiceCollection<Products> products =         //   new DataServiceCollection<Products>         //       (from p in ctx.Products.Expand("Categories")         //        select p);

上記と同じ手順で操作を行うと、今度はデータベース側に更新されるはずです。
DataServiceCollection<T>は、プロパティ通知の実装を内部で持っているため、使用すれば、このように簡単な実装が可能になります。

なお、今回のサンプルは以下にあげておきましたので、ご興味のある方はご確認ください。

https://cid-f1df6ad9b682ecf0.skydrive.live.com/self.aspx/2010^_TechDays/Demo.zip