PropertyChanged.Fodyで変更通知が上手く行かなかった話
C# WPFでソフトを組んでいるときにWindowへ変更通知が上手く行かずにちょっとつまづいたことがあったので覚え書きと同じ問題に直面している方々のお役に立てばと思い共有します。
環境:
- Windows 10 Home
- Visual Studio 2022
- C# .NET 5 WPF
例として以下のようなViewModelを組んでいたとします。画面上の位置をクリックして座標情報を表示させるようなものです。
下記のInfoTextプロパティをXamlのTextBlockへバインディングしているのですが、参照しているプロパティは変更されているはずなのにWindow上へ変更されない、という症状です。
(色分けがないのでかなり見難くてすいません…)
21.11.17追記 コードの色分けを実装してみました!
[AddINotifyPropertyChangedInterface]
public class TestWindowViewModel
{
// 点情報の表示用テキスト
public string InfoText =>
$"Point X: {SelectedPoint.X}\r\n" +
$"Point Y: {SelectedPoint.Y}";
// 点のX, Yを格納するプロパティ
public XyPoint SelectedPoint { get; set; }
// イベントハンドラなどから実行されるメソッド
public void RefreshPoint(int x, int y)
{
SelectedPoint.X = x;
SelectedPoint.Y = y;
}
// X, Yを格納するだけのクラス
[AddINotifyPropertyChangedInterface]
public class XyPoint
{
public double X { get; set; }
public double Y { get; set; }
}
}
期待する動作としては、RefreshPoint()を実行するとSelectedPointが変更されるのでWindowに表示するInfoTextの点情報も更新される、という想定なのですが、その変更通知が上手く行かずずっと「Point X: 0」といった表示のままでした。
色々調べるとよく出てくるのが以下のような項目で、だいたいどれも確認済みだったりします。
- クラスに[AddINotifyPropertyChangedInterface]属性を追加
- FodyWeavers.xmlを確認
- なんか他にも色々あった気がするけど忘れた
他のプロパティに関してはちゃんと変更通知がなされているので大元がおかしいわけではないことは分かるのですが、何故かInfoTextだけが(内部ではちゃんと値が変更されたstringが取得できてました)Windowに反映されないというよく分からない現象でした。
Prism.Mvvm.BindableBase の RaisePropertyChanged(nameof(InfoText)) のようなことができたらRefreshPoint()内に記述すれば済んだのですがそういったものは無さそうで、情報もあまり出てこないので色々試すうちになんとなく原因が掴めました。
原因としてはInfoTextで参照しているプロパティそのもの(SelectedPoint)が変更(set)されているわけではなく、クラスプロパティ内部のプロパティ(SelectedPoint.X)のみが変更されているためにInfoTextに変更通知が発生していなかったんだと思います。
このような場合にRaisePropertyChanged()のような変更通知をしたい場合、プロパティに値をsetすれば変更通知が呼び出されるようなので、InfoTextに以下のように破棄用のsetメソッドを追加し、
public string InfoText
{
get =>
$"Point X: {SelectedPoint.X}\r\n" +
$"Point Y: {SelectedPoint.Y}";
set => _ = value;
}
setメソッドを呼び出すためにInfoTextに適当な空白文字を代入すると意図通り変更通知を行ってくれました。
以上、お役に立てば幸いです。
(検索用)
propertychanged fody not working
- 関連記事
-
-
C# DataGridViewでLinqを使って列集計 2022/10/10
-
PropertyChanged.Fodyで変更通知が上手く行かなかった話 2021/11/12
-
C# で「リソース MaterialDesignTitleTextBlock を解決できません」エラーをどうにかした話 2021/04/21
-
コメント