1

我正在为一个项目使用 WPF 和 MVVM。我有一个带有 GridView 控件的视图。用户可以在网格视图中插入/更新/删除。当任何动作发生时,变化都会反映在 ViewModel 中。这部分工作正常。但是当我想保存数据库中的更改时,我需要一个一个地遍历 ItemSource 中的每个项目。这需要额外的时间才能完成。我只想处理那些更改的项目。

为此,我在我的模型中添加了一个布尔属性来指示项目是否已更改或注释。但问题是,无论何时更改任何其他属性,我都看不到任何设置此布尔属性的方法。

任何机构都可以帮助我怎么做吗?

编辑 我有一个 SelectedItem 属性,我假设每当在 GridView 中选择一个项目时,用户都会更新或插入该行。等等 SelectedItem 属性我已将 SelectedItem 的布尔属性设置为 True。并且在循环保存记录时,我正在保存所有那些在其布尔属性中具有 True 的记录。我知道这不是完美的方式,但现在我没有任何其他方式可以做到这一点。你的意见?

4

3 回答 3

2

您可以订阅模型上的 PropertyChanged 事件并将标志设置为 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

如果你使用 MVVM,你应该有INotifyPropertyChanged的​​实现。您可以添加一些逻辑来在OnPropertyChanged处理程序中设置您的布尔属性。

于 2012-10-04T07:14:17.233 回答
1

如果你愿意依赖于构建时间工具,你可以使用 ILWeaving 来做到这一点。

因此,如果您将FodyPropertyChanged插件结合使用,则开箱即用即可支持 IsDirty 功能。

那么马丁斯的例子可以简化为

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

注意使用 ifIsChanged而不是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 回答