DataContext RefreshおよびPropertyChanging& PropertyChangedイベント
-
03-07-2019 - |
質問
現在のデータコンテキストの外部で特定のエンティティが変更されたことを外部ソースから通知されている状況にあります。エンティティを見つけて、次のようにリフレッシュを呼び出すことができます
MyDataContext.Refresh(RefreshMode.OverwriteCurrentValues、myEntity);
およびエンティティで変更されたプロパティは正しく更新されます。ただし、更新が発生するとINotifyPropertyChanging INotifyPropertyChangedのどちらも発生するように見えず、UIに誤った情報が表示されたままになります。
Refresh()がエンティティの正しいプロパティゲッターとセッターを使用して変更通知イベントを発生させることはできませんが、おそらく同じことを達成する別の方法がありますか?
何か間違ったことをしていますか? 更新よりも良い方法はありますか? 更新が唯一のオプションである場合、回避策はありますか?
解決
同様の問題がありました。 TreeViewにバインドしていたため、ユーザーが編集操作をキャンセルしたことに応答してRefreshを呼び出す必要がありました。 Refresh()
メソッドは元の値をすべて素直に戻しますが、これはTreeView UIに反映されませんでした。全能のグーグルと相談した後、私はこのソリューションに出くわしました:
CollectionViewSource.GetDefaultView(treeViewClusters.ItemsSource).Refresh();
これにより、TreeViewはすべてを強制的に更新するようです。唯一の欠点(そしてそれは非常に大きなものです)は、すべてのツリーノードを折りたたむように見えるため、ユーザーが自分の場所を失うことです。 ItemsSource
をnullに設定し、再び同じように設定することもできます。ただし、バインドされたテキストボックスなどが必要な場合は、この方法の方が簡単です。ひとつひとつを再バインドします。
これよりも良い解決策はありますか?
編集済み: はい、あります...
私の賢い同僚がこの解決策を思い付きました。 Linq2Sqlオブジェクトの部分クラスに、次のコードを追加します。
public void SendPropertiesChanged()
{
foreach (System.Reflection.PropertyInfo prop in this.GetType().GetProperties())
SendPropertyChanged(prop.Name);
}
アプリケーションコードでこれを呼び出すことができます。
context.Refresh(RefreshMode.OverwriteCurrentValues, employee);
employee.SendPropertiesChanged();
すべてのUI要素がメッセージを取得し、適切に更新します。これは、ツリービューコントロールや、UIを「リセット」するように見せたくない場合にも機能します。バインディングを更新するとき。
他のヒント
Refresh()を呼び出すことがわかっている場合は、とにかくその時点でUIを更新しないでください。
PropertyChangingとPropertyChangedは、LINQtoSQL DBMLで生成されたエンティティクラスでセッターを呼び出すことで呼び出されます。 Refresh()を呼び出してもそれは行われません。
[Column(Storage="_DisplayName", DbType="VarChar(50) NOT NULL", CanBeNull=false)]
public string DisplayName
{
get
{
return this._DisplayName;
}
set
{
if ((this._DisplayName != value))
{
this.OnDisplayNameChanging(value);
this.SendPropertyChanging();
this._DisplayName = value;
this.SendPropertyChanged("DisplayName");
this.OnDisplayNameChanged();
}
}
}