【问题标题】:Edit an entity in a new window in wpf在 wpf 的新窗口中编辑实体
【发布时间】:2011-12-14 09:11:51
【问题描述】:

我有一个显示实体列表的窗口,我想在新窗口中编辑 gridview 的选择项(不在网格中)。当我提交我的表单时没有发生错误,但实体在数据库中没有变化!请帮帮我。

在我的列表窗口顶部代码后面:

            private ObservableCollection<Employee> AllEmployeesData { get; set; }
            private ListCollectionView View;

在 window_loaded 中,我使用此方法获取数据:

public void LoadAllEmployees()
    {
        IEnumerable<Employee> data = null;
        using (ArchiveEntities db = new ArchiveEntities())
        {
            data = db.Employees.Include("Department");
            this.AllEmployeesData = new ObservableCollection<Employee>(data);
        }
        CollectionViewSource employeeSource = (CollectionViewSource)this.FindResource("AllEmployeesDataSource");
        employeeSource.Source = this.AllEmployeesData;
        this.View = (ListCollectionView)employeeSource.View;
    }

Editbutton点击事件:

            EditEmployeeView win = new EditEmployeeView();
            View.EditItem(SelectedEmployee);
            win.DataContext = SelectedEmployee;

            if ((bool)win.ShowDialog())
            {
                using (ArchiveEntities db = new ArchiveEntities())
                {
                    Employee employee = db.Employees.Single(x => x.Id == SelectedEmployee.Id);
                    db.Employees.ApplyCurrentValues(employee);
                    db.SaveChanges();
                    View.CommitEdit();
                }
            }
            else
            {
                View.CancelEdit();
            }

以上所有代码都在我的第一个窗口(显示实体列表的窗口)中。 在我的第二个窗口(编辑第一个窗口的选定项目的窗口):

提交按钮点击事件:

        DialogResult = true;
        Close();

我的问题是:当我提交编辑表单时没有发生错误,但数据没有保存在数据库中,当我取消编辑表单时,我收到此错误:

InvalidOperationException 未处理:不支持 CancelEdit 对于当前的编辑项。

【问题讨论】:

    标签: c# wpf data-binding gridview listcollectionview


    【解决方案1】:

    在数据上下文中远离“使用”对于实体框架来说是一种非常糟糕的方法!

    如果您在保存前关闭数据上下文,所有实体结果都会断开连接并另存为无结果。

    试试这个方法,使用类级别的上下文,保持连接并使用实体框架的所有力量

    public mainClass{
    
      private ArchiveEntities db;
      private ObservableCollection<Employee> allEmployeesData;
      private Employee selctedEmplyee;
    
      // property in binding
       public ObservableCollection<Employee> AllEmployeesData { get{return allEmployeesData;} set{allEmployeesData=value; onPropertyChanged("AllEmployeesData"); }
       public Employee SelctedEmplyee { get{return selctedEmplyee;} set{selctedEmplyee=value; onPropertyChanged("SelctedEmplyee"); }
    
      mainWindow (){ //Constructor
    
      db=new ArchiveEntities();
      }
    
      private void onedit(){
         new detailWindow(SelectedEmployee).ShowDialog();
         //reload from db, upadte current element  if modified in the detail window
         SelectedEmployee = db.Employees.Single(x => x.Id == SelectedEmployee.Id);
      }
    
      //no need to save in main window (is only for view)
    
    }
    
    public class detailWindow(){
    
      private ArchiveEntities db;
      private Employee selctedEmplyee;
    
      //employee to modify
      public Employee SelctedEmplyee { get{return selctedEmplyee;} set{selctedEmplyee=value; onPropertyChanged("SelctedEmplyee"); }
    
    
      public detailWindow(Employee SelectedEmployee){
    
        db=new ArchiveEntities; // a new indipendent context
        SelectedEmployee = db.Employees.Single(x => x.Id == SelectedEmployee.Id);
      }
    
      public void onSave(){
        db.SaveChanges(); //effect only in SelectedEmployee
        // if you don'save main window data will not change
      }
    
    
    }
    

    【讨论】:

      【解决方案2】:

      为什么要使用 View.EditItem、View.CommitEdit 和 View.CancelEdit?您所需要的只是您的 win.DataContext = SelectedEmployee。当您将新编辑的数据设置为您的实体时,我没有得到什么?

      using (ArchiveEntities db = new ArchiveEntities())
      {
          Employee employee = db.Employees.Single(x => x.Id == SelectedEmployee.Id);
          db.Employees.ApplyCurrentValues(employee);
          db.SaveChanges();
          View.CommitEdit();
       }
      

      您从 db 获取员工,但未将 SelectedEmployee 中的已编辑数据应用到您的员工。还是我错过了什么?

      SelectedEmployee 是您数据库中的一个实体

      data = db.Employees.Include("Department");
      this.AllEmployeesData = new ObservableCollection<Employee>(data);
      

      那你为什么不使用它并将其保存回数据库?

      db.SaveChanges(SelectedEmployee );
      

      【讨论】:

      • 嗨,blindmeis,我想在另一个窗口(单独的窗口)中编辑选定的项目。如果我想将实体保存在同一个窗口中(在网格中),你的方式是正确的。
      • 好吧,我在我的应用程序中一直使用它,我将 SelectedItem 作为 DataContext 用于第二个视图 - 更改它 - 并将 SelectedItems/更改保存回 db。
      • 顺便说一句,如果您调试您的应用程序,您应该会看到您在 EditEmployeeView win 中所做的所有更改。在“if ((bool)win.ShowDialog())”之后设置一个断点,您的 SelectedItem 应该保存所有更改
      【解决方案3】:

      Employee 类必须实现 IEditableObject 你可以在这里看到一个例子:https://msdn.microsoft.com/en-us/library/system.componentmodel.ieditableobject.aspx 在此实施之后,它应该可以按预期工作

      【讨论】:

        猜你喜欢
        • 2014-01-28
        • 2012-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多