XAML によるデータバインディングは WPF の大きな特徴です。とても便利な機能ではありますが、慣れるまでは難しさを感じる機能でもあります。データバインディングの難しさとしては、ウォッチウィンドウによるプロパティ値の確認ができない点があります。バインドした値が想定通りに表示されず、バインドするパスの修正に手間取ることもあると思います。今回は、データバインディングにまつわるいくつかのテクニックをご紹介し、問題解決に役立てていただければと思います。
- 方法1:デバッグコンソールのエラー確認
- 方法2:XAML バインドエラーウィンドウのエラー確認
- 方法3:IValueConverter を使ったバインド値の確認
- 方法4:Snoop を使ったバインド値の確認
- まとめ
方法1:デバッグコンソールのエラー確認
XAML のデータバインディングが正しく記述されていない場合、デバッグコンソールにエラー内容が出力されます。データバインディングを行っているのに想定通りの表示にならない時には、デバッグコンソールを確認してみましょう。
次のスクリーンショットでは、モデルデータのプロパティ名が 'Label' ですが、Button コントロールの Content プロパティにバインドしようとしているプロパティ名は 'Labela' となってしまっている例です。
実行結果を確認すると、Button コントロールの Content プロパティに値がバインドされておらず、高さもほとんどありません。
データバインディングの結果、想定した表示にならない場合、バインディングの記述に誤りがある可能性があります。デバッグコンソールにエラーが出力されているかを確認してみましょう。
エラーログ:
System.Windows.Data Error: 40 : BindingExpression path error: 'Labela' property not found on 'object' ''ViewModel' (HashCode=6488958)'. BindingExpression:Path=Labela; DataItem='ViewModel' (HashCode=6488958); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
=> ViewModel オブジェクトの 'Labela' プロパティが見つからない、という意味のエラーが出力されていることが分かります。このエラーの内容から、バインディングで記述するプロパティ名が誤っていることが推測できます。
方法2:XAML バインドエラーウィンドウのエラー確認
方法1の「コンソールのエラーを確認」とほぼ同じ内容ですが、XAML バインドエラーウィンドウを利用することでも、エラーの内容を確認することができます。
XAML バインドエラーウィンドウに、方法1と同じ意味のエラーメッセージが表示されていることが分かります。
方法3:IValueConverter を使ったバインド値の確認
続いて、IValueConverter を利用したデバッグ方法を見ていきます。IValueConverter は、バインドデータとバインド先プロパティの間でデータの型が異なる際に、型変換ロジックを加える機能です。そして、型変換ロジックの中はデバッグ実行が可能なため、バインドしている値の確認に利用することができます。IValueConverter によるデバッグは、プロパティが複雑にネストされたオブジェクトのバインディングパスを紐解く際にも便利です。
まずは、IValueConverter を実装するクラスを用意します。ここでは MyValueConverter とします。MainWindow.xaml.cs に、下記実装を加えます。
public class MyValueConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
MyValueConverter クラスを、XAML 側で参照します。ここでは、キー名に "conv" を指定しています。そして、Button コントロールの Content プロパティのバインディングに、MyValueConverter クラスを加えます。
<Window xmlns:igDP="http://infragistics.com/DataPresenter" x:Class="WPF_Binding_Demo.MainWindow" ...> <Window.Resources> <local:MyValueConverter x:Key="conv"/> </Window.Resources> <Grid> ... <TextBox .../> <Button HorizontalAlignment="Left" Margin="163,10,0,0" VerticalAlignment="Top" Width="79" Content="{Binding Path=., Converter={StaticResource conv}}"/> <igDP:XamDataGrid ... /> </Grid> </Window>
MyValueConverter クラスの Convert メソッドにブレイクポイントを貼ることで、アプリケーションのデバッグ実行時に、Convert メソッド内で実行を止めることができます。Convert メソッドの第一引数をウォッチウィンドウに入れると、Button コントロールの Content プロパティにバインドされている DataContext の内容を確認することができます。Path の右辺に Keyword プロパティや Label プロパティが指定できることが分かります。
方法4:Snoop を使ったバインド値の確認
ここまで、Visual Studio に提供されている機能を用いてデータバインディングのエラーや状態を確認する方法を見てきました。最後に、Snoop というツールを利用することでデータバインディングの状態を調べる方法をご紹介します。
Snoop に関する情報は、下記 GitHub をご覧ください。
GitHub - snoopwpf/snoopwpf: Snoop - The WPF Spy Utility
Snoop の操作方法
デバッグ対象の WPF アプリケーションと並行して、Snoop を実行します。そして、Snoop の右側のクロスヘアボタン(クロスヘアボタンは二つありますが、右側のクロスヘアボタンを利用)をクリックしながら調査対象の WPF アプリケーションにマウスカーソルをドロップします。すると、Snoop のプロパティウィンドウが表示されます。Snoop プロパティウィンドウの左側に、調査対象の WPF アプリケーションのビジュアルツリーが表示されます。プロパティウィンドウの右側には、UI 要素の状態(各種プロパティの状態、DataContext の状態、イベントの発生状況など)を確認することができます。Snoop 画面が表示された後に、WPF アプリケーションの調査したい UI 要素上で Ctrl + Shift を押下することで、その UI 要素の状態を表示することができます。
Data Context タブでは、Button コントロールの DataContext の値を確認することができます。
まとめ
今回は、WPF XAML データバインディングのテクニックを紹介しました。色々な方法があるので、好みに応じて使い分けてみてください。 説明の過程で利用したサンプルはこちらにあります。
弊社では WPF の要点をまとめた、技術トレーニングを提供しています。オンデマンド形式で、ご都合の良い時間に、繰り返し学習することができます。また、技術トレーニングの内容に関して、トレーニング購入後、30 日間お問い合わせいただけます!これから WPF について網羅的に学習されたい方、WPF を採用したプロジェクトへの参画が決まった方におすすめの内容となっております。ぜひご活用ください!