WPF - 当UpdateSourceTrigger = Explicit时,如何在数据绑定ItemsControl中添加/删除项目

时间:2014-07-09 20:52:41

标签: c# wpf data-binding itemscontrol

我有一个窗口,它基本上是一个显示联系人所有数据的对话框。用户可以编辑数据并按“保存”以保存更改。 UpdateSourceTrigger对所有数据绑定都是显式的,以便用户能够取消所有修改。

现在,Contact有一些地址,我将这些地址绑定到ListBox的ItemsSource。 现在我必须能够添加/删除地址,但是我想在不修改底层集合的情况下这样做因为我不希望在用户“保存”之前对我的Contact对象进行任何修改“按钮点击。

这是最好的做法吗?

2 个答案:

答案 0 :(得分:2)

您应该存储对象持久状态的只读副本,并允许用户修改参与绑定的任何属性,并在UI中正在编辑的对象的UI中进行编辑。您可以使用存储的只读持久状态副本来将UI中要修改的对象与持久值进行比较,必要时还原原始值并确定对象是否已修改并且“可持久”...

我是这样做的:

public class SomeBusinessObject : INotifyPropertyChanged
{
    private int id;
    public int Id
    {
        get { return id; }
        set { id = value; OnPropertyChanged("Id"); }
    }
    private int property1;
    public int Property1
    {
        get { return property1; }
        set { property1 = value; OnPropertyChanged("Property1"); }
    }
    private string property2;
    public string Property2
    {
        get { return property2; }
        set { property2 = value; OnPropertyChanged("Property2"); }
    }
    //... Other properties

    public bool IsModified { get; set; }
    public bool IsPersistable { get; set; }
    public SomeBusinessObject PersistedState { get; private set; }

    public SomeBusinessObject(int id, int p1, string p2, savePersistedState = false)
    {
        Id = id;
        Property1 = p1;
        Property2 = p2;
        //Set other properties
        if (savePersistedState) PersistedState = new SomeBusinessObject(id, p1, p2)
    }
}

正如您所见,默认情况下,对象不会保存其持久状态,只允许您将对象的持久状态副本保留为对象的另一个属性(例如,在UI中编辑时)。

此方法与实现INotifyPropertyChanged接口相结合,允许您订阅对象的PropertyChanged事件,并根据BI规则设置IsModifiedIsPersistable标志,并恢复持久化对象的状态非常容易从只读(注意首次实例化对象时创建的private set;属性setter)PersistedState副本。

它还允许您非常轻松地实现WPF命令的CanExecuteChanged事件。例如,表单上的“保存”按钮的SaveCommand可以只检查对象的IsPersistable标志,以确定对象是否“可持久”以及是否应该启用该按钮(显然您需要更改标志)在根据某些业务逻辑处理PropertyChanged事件并将其与持久状态对象进行比较时...

答案 1 :(得分:1)

如果我理解,您已经使用UpdateSourceTrigger = Explicit设置了一种机制,其中UI更改被推迟。

但是这种机制对于可以添加/删除的集合不起作用,因为现在您正在处理引用类型。这意味着它的值将在绑定源和目标之间共享,因此根据定义,更改一个是更改另一个。因此,无论如何,您将不得不为UI创建一个单独的集合副本。

我建议考虑一种与显式源更新完全不同的方法 - 这似乎是一种多方面的冒险方法(例如,如果源模型没有获得,则不能进行任何每个属性的验证立即更新)。

例如,也许您可​​以维护两个单独的对象,并在类上使用“复制”方法将属性值(标识属性除外)从一个复制到另一个。