インフラジスティックス・ジャパン株式会社Blog

インフラジスティックス・ジャパン株式会社のチームメンバーが技術トレンド、製品Tips、サポート情報からライセンス、日々の業務から感じることなど、さまざまなトピックについてお伝えするBlogです。

データグリッド (xamDataGrid) で学ぶ WPF のデータバインディングの基礎について

こんにちは! テクニカルコンサルティングチームの古堅です。

本記事では、WPF入門者に向けた xamDataGrid をご利用頂く上で、データバインディングの陥りやすい罠について紹介します。

データグリッドで学ぶ、データバインディング基礎

前提

データバインディングでは、各コントロールが何とバインドされているか?という観点が非常に重要になってきます。

本記事では、以下のような ViewModel をご用意しました。

f:id:furugen098:20220408171912p:plain

3つのプロパティを持っています。

Name プロパティは、文字列で名前を入力するプロパティ

Records プロパティは、配列のデータ

OnDeleteCommand は、削除ボタンをクリックした際に連動するコマンド

としてそれぞれ設けています。それでは、各プロパティを View にバインドしていきます。

Name プロパティをバインディング

まず、データバインディングの基本となる Window コントロールの DataContext に対象の ViewModel を設定します

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new MainWindowViewModel();

    }
}

こうする事で、MainWindow と MainWindowViewModel のデータバインディングが行われているための準備が出来ました。

次に、テキストボックスに ViewModel.Name を設定しみましょう。

 <TextBox Text="{Binding Name}"/>

TextBox の Text プロパティにデータバインディングされました。

f:id:furugen098:20220408165315g:plain

f:id:furugen098:20220408172333p:plain

Records プロパティをバインディング

では、次にデータグリッドもバインドしてみます。

<ig:XamDataGrid DataSource="{Binding Records}" />

データグリッドに配列データが表示されましたね。

f:id:furugen098:20220408165802g:plain

本題!ここからが陥りやすい罠です

では、次に xamDataGrid のバインドしたレコード中に、ボタンを配置して、ViewModel の削除コマンドとバインドしたいと思います。

<ig:TemplateField BindingType="Unbound" Width="40">
    <ig:TemplateField.DisplayTemplate>
        <DataTemplate>
            <Button Command="{Binding OnRemoveCommand}">削除</Button>
        </DataTemplate>
    </ig:TemplateField.DisplayTemplate>
</ig:TemplateField>

早速ですが、削除ボタンをクリックしてみますが、、、全く反応がありません!

f:id:furugen098:20220408173857g:plain

データバインディングの状態を確認してみると、Binding エラーが発生していることがわかります。

f:id:furugen098:20220408173236p:plain

実は、グリッドで展開された各レコードは、Records の各レコードとデータバインディングされています。

イメージとしては、以下ですね。

各レコードは、ViewModel.Records[0] や、ViewModel.Records[1] とバインドされています。

f:id:furugen098:20220408175643p:plain

そのため、削除ボタンの中で <Button Command="{Binding OnRemoveCommand}>と記載すると、ViewModel.Records[0] 等がバインディングの対象となり、ViewModel.OnRemoveCommand とバインディングするためには、ViewModel をバインディングするためには、上位階層を見る必要があります。

解決方法としては、以下のようにデータバインディングの対象を親要素を Window まで(RelativeSource Mode=FindAncestor)遡ることで、ViewModel.OnRemoveCommand とバインディグができるようになります。

<ig:TemplateField BindingType="Unbound" Width="40">
    <ig:TemplateField.DisplayTemplate>
        <DataTemplate>
            <Button Command="{Binding DataContext.OnRemoveCommand,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">削除</Button>
        </DataTemplate>
    </ig:TemplateField.DisplayTemplate>
</ig:TemplateField>

動作してみましょう。各レコードが削除できるようになりました!

f:id:furugen098:20220408180507g:plain

サンプルコード

本記事で利用したサンプルコードは以下よりダウンロードできます。

https://kb.jp.infragistics.com/wp-content/uploads/2022/04/Grid_ViewModelSample.zip

まとめ

弊社のプライオリティーサポートは、こういったプラットフォームのお悩みも相談できます。

オンライン無料相談会も随時開催していますので、ご興味のある方は以下の無料相談会よりお申込みください!

技術サポート・無料オンライン相談会をご利用ください

インフラジスティックスのUI製品は多くの機能を備えているためドキュメントの情報量も多く、なかなかお探しの情報に辿り着けない場合もあります。そういった際はお気軽に技術サポートや、製品導入支援担当との無料オンライン相談会をご予約いただくことで検証時間を節約可能ですので、ぜひご活用ください。
技術サポートへの問い合わせ方法を確認する
無料オンライン相談会を予約する