1

プロジェクトにWPFとMVVMを使用しています。GridViewコントロールを備えたビューがあります。ユーザーはグリッドビューで挿入/更新/削除できます。アクションのいずれかが発生すると、変更がViewModelに反映されます。この部分は正常に機能しています。ただし、データベースに変更を保存する場合は、ItemSourceの各アイテムを1つずつループする必要があります。完了するまでに余分な時間がかかります。変更されたアイテムのみを処理したい。

これを実現するために、モデルにブールプロパティを追加して、アイテムが変更されたかメモされたかを示します。しかし、問題は、他のプロパティが変更されるたびに、このブールプロパティを設定する方法がわからないことです。

どんな体も私にそれをする方法を助けてくれますか?

編集 SelectedItemプロパティがあり、GridViewでアイテムが選択されるたびに、ユーザーが行を更新または挿入すると想定しています。そのため、SelectedItemプロパティでSelectedItemのブールプロパティをTrueに設定しました。レコードを保存するためにループしている間、ブールプロパティにTrueを持つすべてのレコードを保存しています。私はそれが完全な方法ではないことを知っていますが、今のところ私はそれを行う他の方法がありません。あなたの考え?

4

3 に答える 3

2

Model で PropertyChanged イベントをサブスクライブし、Flag を True に設定できます。ただし、データベースからデータをロードした後、Flag を false に設定する必要があることに注意してください。これは、モデルの初期化でも propertychanged イベントが呼び出されるためです。

IsDirty-Flag を持つクラスの例:

public class Sample : INotifyPropertyChanged
{
    private int id;
    private string name;
    private bool isDirty;

    public event PropertyChangedEventHandler PropertyChanged;

    public int Id
    {
        get { return id; }
        set
        {
            if(id != value)
            {
                id = value;
                RaisePropertyChanged("Id");
            }
        }
    }

    public string Name
    {
        get { return name; }
        set
        {
            if (name != value)
            {
                name = value;
                RaisePropertyChanged("Name");
            }
        }
    }

    public bool IsDirty
    {
        get { return isDirty; }
        set
        {
            if (isDirty != value)
            {
                isDirty = value;
                RaisePropertyChanged("IsDirty");
            }
        }
    }

    protected virtual void RaisePropertyChanged(string propertyName)
    {
        if (propertyName != "IsDirty")
        {
            IsDirty = true;
        }

        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

ObservableCollection を使用している場合は、イベントハンドラを追加して、新しく追加または削除された行を追跡することもできます

于 2012-10-04T07:16:51.840 に答える
1

ビルド時のツールに依存する場合は、ILWeaving を使用してこれを行うことができます。

したがって、FodyPropertyChangedアドインと組み合わせると、IsDirty 機能がすぐにサポートされます。

次に、Martins の例を次のように単純化できます。

public class Sample : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsChanged { get; set; }
}

IsChangedの代わりにif を使用することに注意してくださいIsDirty

そして、これはコンパイルされたアセンブリに存在します

public class Sample : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    int id;
    public int Id
    {
        get { return id; }
        set
        {
            if (id != value)
            {
                id = value;
                IsChanged = true;
                OnPropertyChanged("Id");
            }
        }
    }

    bool isChanged;
    public bool IsChanged
    {
        get { return isChanged; }
        set
        {
            if (isChanged != value)
            {
                isChanged = value;
                OnPropertyChanged("IsChanged");
            }
        }
    }

    string name;
    public string Name
    {
        get { return name; }
        set
        {
            if (!string.Equals(name, value, StringComparison.Ordinal))
            {
                name = value;
                IsChanged = true;
                OnPropertyChanged("Name");
            }
        }
    }
}
于 2012-10-07T05:26:00.820 に答える
1

MVVM を使用する場合は、INotifyPropertyChangedを実装する必要があります。また、 OnPropertyChangedハンドラーでブール値のプロパティを設定するロジックを追加できます。

于 2012-10-04T07:14:17.233 に答える