クラス内のデータとコントロールのデータを同期させる
どうもこんばんは。
最近WPFアプリに手を出してみました。
フォームアプリしか作った事ないので、最初は慣れないし、『XAMLって何よ』状態だったけど、『これはコレ』で線引きして考えて作っていったらそうでもなかった。
固定概念って怖いね!
今回は、最近WPFアプリ開発でデータ格納クラス内のプロパティデータとコントロールデータを同期させる件でほぼ一日費やしてしまったので、その備忘録。
なぜかソース⇒ターゲットがいかない
コントロール内のデータを変更したら、問題なくオブジェクト内のデータは変更されているようなのですが、なぜかオブジェクト内のデータを変更してもコントロールのデータは変更されない。
色々調べても、『ModeをTwoWayにすれば同期するよー』って書いてあるんですが、コントロール間ではそれでするのかもしれませんが(まだ調べてないです)、どうやらクラスとかそういったデータ間ではしない模様です。
まずはModeを双方向にする
まずはコントロールのバインディングの設定を双方向します。
C#
[csharp]
public class TestData
{
public string Title { get; set;}
}
[/csharp]
XAML
[xml]
<Label x:Name="lbl_title_main" Content="{Binding Title, Mode=TwoWay}" Margin="0,0,2.721,0" Foreground="White" FontFamily="Yu Gothic" FontSize="26.667" Padding="0" Height="24.936" d:LayoutOverrides="TopPosition, BottomPosition"/>
[/xml]
ですがこれだけでも上記の通り、『コントロール⇒バインド元』は同期しますが、『バインド元⇒コントロール』は同期されません。
どうやらコントロールは、既に依存関係プロパティなのに対しBindingされたオブジェクト(自作クラスとか)にはそういった機能が備わっていないため、『INotifyPropertyChanged』を実装してあげないといけないらしい。
INotifyPropertyChangedを実装
ということで、インターフェースを実装。
各プロパティが変更された段階で『OnPropertyChanged』イベントで通知を行うといった感じ?
C#
[csharp]
public class TestData : INotifyPropertyChanged
{
private string _Title;
public string Title
{
get { return _Title; }
set
{
_Title = value;
OnPropertyChanged("Title");
}
}
/// <summary>
/// 関連付けられたプロパティ 変更 ハンドラ
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 関連付けられたプロパティ 変更
/// </summary>
/// <param name="specifiedProperty">関連付けられたプロパティ名</param>
protected void OnPropertyChanged(string propertyName = "")
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
[/csharp]
これでソースが変更された際にもコントロール側のデータもちゃんと同期されました!
まとめ
便利だし管理も楽なのに、ここに来て双方向同期させる為に全プロパティにゴニョゴニョしなきゃいけないのはとてもめんどくさい気がする。
なんか手間としては、イベント時にコントロール内のデータをまとめるのとあんまり変わらなそう。
まぁでも、同期させたり変更させた際に追記する部分とかが、ある意味ピンポイントでまとまっているので、プロパティが増えたとか減ったっていう時の管理のしやすさは便利かなー程度。
コードはちょっと増えるから見栄えはあんまよろしくないですね。
今更ですが、フォームアプリでもバインディングができるのを今回の件で初めて知りました(笑)
やっぱり、フォトショとかイラレもそうなんですが、趣味から始めた独学だと当たり前の機能とかを知らないことが結構多く初めて当たり前の知識を取り入れて、さらに視野が広がった!って事結構多いです。
基本は大事ですね!!
ちなみに、今回は@ITさんのページを参考にしました。
こっちのがわかりやすいね(笑)