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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://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("http://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>は、プロパティ通知の実装を内部で持っているため、使用すれば、このように簡単な実装が可能になります。

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

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

Skip to main content