かずきのBlog
C#やJavaやRubyとメモ書き

目次

Blog 利用状況
  • 投稿数 - 362
  • 記事 - 1
  • コメント - 424
  • トラックバック - 97
ニュース
  • 思い出は、いっぱい。
コメント
プログラマ的自己紹介
  • C#とRubyを趣味で。Javaを仕事で使ってやってます。 WPFをコツコツ勉強中。 IDE大好き。Visual Studio, Eclipse, NetBeansを使用中
お気に入りのツール/IDE
  • Visual Studio 2008 std
  • Eclipse
  • NetBeans6.0以降
  • 自作のツール
プロフィール
  • 大田 一希
  • 1981年1月30日産まれ
  • AB型
  • 左利き
経歴
  • 1993年 海田中学校 入学
  • 1996年 広島県立安芸南高等学校 入学
  • 1999年 某大学 環境情報学科 入学
  • 2003年 某大学 大学院 環境学研究科 入学
  • 2005年 就職して上京
  • 今に至る
アクセサリ
  • あわせて読みたい
  • ログ解析ネット証券

書庫

日記カテゴリ

 

1つ前の記事でWindowsFormを使って作ったものと似たようなものをWPFのListViewを使って作ってみようと思う。WPFのListViewのほうは、さくっとやるだけじゃ編集とかはサポートされないので、とりあえず読み取り専用で作る。

ついでに、2つ前の記事でやったようにWindows FormにWPFのコントロールを埋め込む形で1つ前の記事のWindows Formアプリケーションに埋め込んでWPFとDataGridViewの見た目の比較もできるように作ってみようと思う。

まずは、WPFのUserControlを作成する。名前はDataSetViewerにした。名前に反して汎用的な部品じゃないのを作る予定なのでご了承を。とりあえず、簡単にEmployeesテーブルの中身を出すところまでやってみる。
特に悩むことも無い。DataContextにEmployeesDataTableが設定されているという前提でぽちぽちListViewを組み立てただけだ。

<UserControl x:Class="DatabaseApp.DataSetViewer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <ListView ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}" />
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
                    <GridViewColumn Header="DeptID" DisplayMemberBinding="{Binding DeptID}" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</UserControl>

これを、フォームの下側に貼り付ける。
image

フォームのロードイベントで、WPFのユーザコントロールのDataContextにEmployeesDataTableのインスタンスを設定するコードを追加する。

        private void Form1_Load(object sender, EventArgs e)
        {
            // データ取得
            this.departmentsTableAdapter.Fill(this.empMngDataSet.Departments);
            this.customersTableAdapter.Fill(this.empMngDataSet.Customers);
            this.employeesTableAdapter.Fill(this.empMngDataSet.Employees);

            dataSetViewer1.DataContext = empMngDataSet.Employees;
        }

そして、実行するとEmployeesDataTableのデータがWPFのListViewのほうにも出てる!
image

次は右側に、選択した従業員の顧客の情報も出してみようと思う。
これは、顧客情報を表示する側のBindingのPathに何を渡すかがわかれば簡単。DataTableのRelationの名前を渡せばOK。DataSetデザイナは、外部キーの名前をRelationの名前にしてくれるので、FK_CustomersEmployeesをBindingのPathに設定すればいける。

<UserControl x:Class="DatabaseApp.DataSetViewer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.ColumnDefinitions>
            <!-- 従業員データ表示用の列 -->
            <ColumnDefinition />
            <!-- 顧客データ表示用の列 -->
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <ListView ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}" />
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
                    <GridViewColumn Header="DeptID" DisplayMemberBinding="{Binding DeptID}" />
                </GridView>
            </ListView.View>
        </ListView>
        <!-- DataTableのリレーション名をパスに指定することでバインドができる -->
        <ListView Grid.Column="1" ItemsSource="{Binding FK_CustomersEmployees}" IsSynchronizedWithCurrentItem="True">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}" />
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
                    <GridViewColumn Header="EmployeeID" DisplayMemberBinding="{Binding DeptID}" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</UserControl>

ばっちり出た。いい感じ。
image

最後に、従業員の所属する部署名を出してみようと思う。
正直、これにちょっと苦労した。というのも、ListViewのItemsSourceにはEmployeesDataTableを指定してるから、EmployeesRowがListViewの各行にあたるだろうと思ってたら実はDataRowViewのインスタンスだった。なので、何も考えずにBindingのPathにDataSetデザイナが作ってくれるDepartmentsRowプロパティのNameプロパティを指定しても、うまいこと表示されない。

DataRowViewのRowプロパティのDepartmentsRowのNameプロパティという感じでPathを指定することでうまくいった。メモメモ

<UserControl x:Class="DatabaseApp.DataSetViewer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.ColumnDefinitions>
            <!-- 従業員データ表示用の列 -->
            <ColumnDefinition />
            <!-- 顧客データ表示用の列 -->
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <ListView ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}" />
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
                    <GridViewColumn Header="DeptID" DisplayMemberBinding="{Binding DeptID}" />
                    <!-- DataRowViewに対してBindingのPathを書く! -->
                    <GridViewColumn Header="DeptName" DisplayMemberBinding="{Binding Row.DepartmentsRow.Name}" />
                </GridView>
            </ListView.View>
        </ListView>
        <!-- DataTableのリレーション名をパスに指定することでバインドができる -->
        <ListView Grid.Column="1" ItemsSource="{Binding FK_CustomersEmployees}" IsSynchronizedWithCurrentItem="True">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}" />
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
                    <GridViewColumn Header="EmployeeID" DisplayMemberBinding="{Binding DeptID}" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</UserControl>

実行結果。ばっちり表示できてる。

image

ということで、DataTableをWPFにバインドするときのメモでした。

ただ、注意しないといけないのは、DataGridViewからデータの追加をしたときにはWPFのほうも追従してくれるけど、従業員名の変更とかは追従してくれないということ。要注意や!

投稿日時 : 2008年7月2日 0:38
コメント
  • # re: [WPF][ADO.NET]DataSet(DataTable)をWPFのListViewにバインドしてみよう
    minminnana
    Posted @ 2008/07/25 17:33
    初めまして、いつも参考にさせていただいております。
    もしよろしければ教えていただきたいのですが、
    BindingNavigatorコントロールで行を進めた時、WPFコントロールの方に反映しますでしょうか?
  • # re: [WPF][ADO.NET]DataSet(DataTable)をWPFのListViewにバインドしてみよう
    かずき
    Posted @ 2008/08/12 16:24
    そこらへんは確か同期しなかったように思います…
  • # re: [WPF][ADO.NET]DataSet(DataTable)をWPFのListViewにバインドしてみよう
    minminnana
    Posted @ 2008/08/18 15:24
    DataTableにはINotifyPropertyChangedが実装されていないからということなんでしょうかね・・・。

    回答いただきありがとうございました。
タイトル  
名前  
Url
コメント