この問題はしばらく頭を悩ませており、プロジェクトの進行を妨げています。コントロールが ViewModel にバインドされた WPF XAML フォームを考えてみましょう。(データには Caliburn.Micro MVVM フレームワークと Entity Framework を使用しています)。Initialize()
データベースからフォームのデータをロードし、PropertyChanged イベント ハンドラーを設定するために、メソッドがシェルによって呼び出されます。フォームに変更されたデータがあるかどうかを追跡するIsDirty
フラグがあります。IsDirty
データが変更されたときに有効になるように、プロパティにバインドされた [保存] ボタンがあります。
// Sample code; forms have many controls....
// this is the property that the controls are bound to
public Entity BoundData { get; set; }
public void Initialize()
{
// this is an example line where I query the database from the Entity Framework ObjectContext...
BoundData = objectContext.DataTable.Where(entity => entity.ID == 1).SingleOrDefault();
// this is to cause the form bindings to retrieve data from the BoundData entity
NotifyOfPropertyChange("BoundData");
// wire up the PropertyChanged event handler
BoundData.PropertyChanged += BoundData_PropertyChanged;
IsDirty = false;
}
void BoundData_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
IsDirty = true;
}
// implementation of the IsDirty flag
public bool IsDirty
{
get
{
return _isDirty;
}
set
{
_isDirty = value;
NotifyOfPropertyChange("IsDirty");
}
}
問題は、メソッドが終了BoundData_PropertyChanged
した後にフォームがデータベースから初期化されるために、イベント ハンドラーがヒットすることです。Initialize()
そのためIsDirty
、フォームがロードされたばかりで、ユーザーが何も変更していない場合でも、フラグは true に設定され、[保存] ボタンが有効になります。私は何が欠けていますか?確かにこれはよくある問題ですが、良い解決策を見つけることができませんでした。これは私の最初の MVVM プロジェクトなので、基本的な概念が欠けている可能性は十分にあります。
更新:明確にするために、問題は、すべてのバインディングの更新が完了したときに発生するイベントまたはコールバックにフックできる必要があるため、PropertyChanged イベント ハンドラーを接続できることだと思います。