Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF-当UpdateSourceTrigger=Explicit时如何向数据绑定项控件添加/删除项_C#_Wpf_Data Binding_Itemscontrol - Fatal编程技术网

C# WPF-当UpdateSourceTrigger=Explicit时如何向数据绑定项控件添加/删除项

C# WPF-当UpdateSourceTrigger=Explicit时如何向数据绑定项控件添加/删除项,c#,wpf,data-binding,itemscontrol,C#,Wpf,Data Binding,Itemscontrol,我有一个窗口,它基本上是一个对话框,显示联系人的所有数据。用户可以编辑数据并按“保存”保存更改。UpdateSourceTrigger对于所有数据绑定都是显式的,用户可以取消所有修改 现在,联系人有一些地址,我将这些地址绑定到列表框的ItemsSource。 现在,我必须能够添加/删除地址,但我希望在不修改基础集合的情况下添加/删除地址,因为我不希望在用户单击“保存”按钮之前对联系人对象进行任何修改 是否有最佳实践?如果我理解,您已经使用UpdateSourceTrigger=Explicit设

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

现在,联系人有一些地址,我将这些地址绑定到列表框的ItemsSource。 现在,我必须能够添加/删除地址,但我希望在不修改基础集合的情况下添加/删除地址,因为我不希望在用户单击“保存”按钮之前对联系人对象进行任何修改


是否有最佳实践?

如果我理解,您已经使用UpdateSourceTrigger=Explicit设置了一种机制,在该机制中用户界面更改被延迟

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

我建议考虑一种与显式源代码更新完全不同的方法——这在很多方面似乎都是一种危险的方法(例如,如果源模型没有立即更新,则无法进行任何每个属性的验证)


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

您应该存储对象持久状态的只读副本,并允许用户修改参与绑定的任何属性,以及在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规则设置
IsModified
IsPersistable
标志,并非常容易地从只读模式恢复对象的持久状态(注意
私有集;
属性setter)
PersistedState
copy在对象第一次实例化时创建


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

非常感谢!由于代码示例,我将Dean的帖子标记为答案,但这确实有助于您俩编写基本相同的内容。