Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.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# 防止对一个窗口上的对象所做的更改影响另一个窗口_C#_Sql_Wpf_Dapper - Fatal编程技术网

C# 防止对一个窗口上的对象所做的更改影响另一个窗口

C# 防止对一个窗口上的对象所做的更改影响另一个窗口,c#,sql,wpf,dapper,C#,Sql,Wpf,Dapper,在我的主窗口上有一个datagrid,它从SQL加载对象列表: if (PartView.Instance.CurrentPart != null) { DgSupplierData.ItemsSource = partData.GetAllPartSuppliersByPart(PartView.Instance.CurrentPart.Id); } partData只是一个助手类,它使用dapper从存储过程加载列表 当用户双击一行时,将打开一个“编辑窗口”,这是一个基本窗口,将行

在我的主窗口上有一个datagrid,它从SQL加载对象列表:

if (PartView.Instance.CurrentPart != null)
{
    DgSupplierData.ItemsSource = partData.GetAllPartSuppliersByPart(PartView.Instance.CurrentPart.Id);
}
partData只是一个助手类,它使用dapper从存储过程加载列表

当用户双击一行时,将打开一个“编辑窗口”,这是一个基本窗口,将行数据分配给用户要编辑的自定义对象(PartSupplierModel)。一旦他们编辑数据并点击save按钮,一个存储过程就会将数据保存到SQL Server(非常简单,工作正常)。但是,如果用户对任何文本框进行了任何更改,但随后决定不保存更改,并关闭表单,然后重新选择同一行,则表单将保留所做的更改(尽管不会保存到SQL Server,因为未调用按钮事件,这正是我们想要的)。我希望数据不会更改原始表中的源,除非单击了“编辑/保存”按钮。我相信这是由于我装订对象的方式?然而,作为WPF的新手,我很难理解如何防止这种功能

示例:这显示了我如何在编辑表单上设置文本框

<TextBox x:Name="TxtManufacturer"
                     Text="{Binding Manufacturer, UpdateSourceTrigger=PropertyChanged}"
                     VerticalAlignment="Center"
                     Height="25"
                     MaxLength="150"/>

没有足够的信息来有效地回答这个问题,但我希望它能给出一些提示:

    private PartSupplierModel _partSupplier = new PartSupplierModel();

    public PartSupplierView(PartSupplierModel supplierData = null, int partId = 0)
    {
        InitializeComponent();

        _partSupplier = supplierData;

        this.DataContext = _partSupplier;
    }
没有必要说
\u partSupplier=new…
,因为您在构造函数中所做的唯一一件事就是使用传入的变量
supplierData来覆盖它

这样做不会执行任何类型的克隆或复制,它只是意味着您在内存中某处有某个对象,您可以将窗体指向它

用户进行编辑,更改内存中的原始对象,关闭窗体,但下一个o保持更改。如果你打开一个新窗体,它是否是新的并不重要,它会指向内存中原来修改过的对象

你不妨这样写:

    public PartSupplierView(PartSupplierModel supplierData = null, int partId = 0)
    {
        InitializeComponent();

        this.DataContext = supplierData;
    }
这是否有助于您理解,如果您从未执行过取消真实用户所做更改的操作,或者您从未刷新作为
supplierData
传入的对象,那么每次打开此表单时,它都会查看不断演变、更改的对象

解决此问题的方法有很多,但通常归结为:

  • 如果用户取消或将其数据合并到“主”对象中,则处理副本并将其丢弃;如果用户不这样做,则将其保存到数据库中(数据库是主对象)
  • 在数据模型中构建一个工具,用于跟踪原始值和更改的值,并在用户取消时将更改的值恢复为原始值(每个属性由两个字段(原始/当前)支持。首次创建时,这两个字段都将写入,但此后仅更新当前字段。根据您的操作,接受/拒绝更改的两种方法用于将原始字段复制到当前字段(拒绝)或当前字段复制到原始字段(接受)。数据容器(如DataTable/DataRow)可执行此操作
  • 如果用户单击“取消”,则刷新数据库中的对象-这与“处理副本”大致相同,因为数据库是真实的来源,而本地对象是非常临时的。这种方式会更频繁地使用数据库
我们无法具体说明该做什么,因为您的问题没有给出任何有关
供应商数据
来自何处、如何存储、预期生命周期等的信息。这是您需要决定的;此表单正在编辑该对象,因此您想如何处理还原更改?再次获取该对象/从m是自身或内部跟踪的本地副本,并且能够撤消?对此没有正确/错误的答案-这取决于系统的并发性和性能要求

*除非它有助于避免InitializeComponent中由于nullref原因而崩溃,但这是我的观点的辅助,即创建一个新的是没有用的,因为您所做的只是扔掉新的并编辑原始数据

public PartSupplierView()是一个表单的构造函数,在“新建”时只调用一次如果您创建一个Load()方法并将行放置为:this.DataContext=\u partSupplier;那么每次使用Show()方法时,DGV都将加载原始数据。
    public PartSupplierView(PartSupplierModel supplierData = null, int partId = 0)
    {
        InitializeComponent();

        this.DataContext = supplierData;
    }