WPF窗口DataContext错误“列名无效”

时间:2016-12-24 18:00:13

标签: c# wpf entity-framework xaml ef-code-first

尝试将DataContext设置为WPF窗口我正在使用CodeFirst,这里是代码

    public class Employee
{
    [Key]
    public int EmployeeId { get; set; }

    [Display(Name = "FullName")]
    [Required(ErrorMessage = "FullNameRequired")]
    public string FullName { get; set; }

    public string Address { get; set; }

    public string Phone { get; set; }

    public double Salary { get; set; }

    public string Email { get; set; }

    public string Job { get; set; }

}

public class EmployeeVM
{
    SDBContext db = new SDBContext();

    public List<Employee> Employees;

    public EmployeeVM()
    {
        this.Employees= db.Employees.ToList();
    }
}

将ViewModel添加到窗口datacontext

 xmlns:VM="clr-namespace:Project_Test.ViewModels"

<Window.DataContext>
    <VM:EmployeeVM/>
</Window.DataContext>

但我收到错误“无效的列名Job”

我尝试将'Employees'Collection绑定到DataGrid,但它不起作用

ItemsSource="{Binding Employees}"

在代码隐藏中完成它并且工作正常

SDBContext db = new SDBContext();
public MainWindow()
{
    InitializeComponent();

    DG_Employees.ItemsSource = db.Employees.ToList();
}

更新

我删除了“Job”属性并收到了另一个错误: “自创建数据库以来,支持上下文的模型已经发生了变化。请考虑首先使用代码”

1 个答案:

答案 0 :(得分:0)

对于您的第一种工作方式,您的Employees必须是属性,而不是字段,如下所示:

public class EmployeeVM
{
    SDBContext db = new SDBContext();

    public List<Employee> Employees {get;set;}

    public EmployeeVM()
    {
        this.Employees= db.Employees.ToList();
    }
}

然后,当您将ItemsSource绑定到Employees时,它应该可以工作。

但是

如果您计划在除costructor之外的某个地方从数据库加载Employees,那么您的EmployeeVM should implement INotifyPropertyChangedEmployees属性应该在更改时引发PropertyChanged事件,因此您的Viewmodel应如下所示:

public class EmployeeVM : INotifyPropertyChanged
{
    SDBContext db = new SDBContext();

    private List<Employee> _employees;
    public List<Employee> Employees
    {
        get { return _employees; }
        set
        {
            if (Equals(value, _employees)) return;
            _employees = value;
            OnPropertyChanged("Employees");
        }
    }

    public EmployeeVM()
    {
        this.Employees = db.Employees.ToList();
    }


    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

然后,每次执行this.Employees = /..something../绑定的DataGrid都应该看到ItemsSource已更改。

但更重要的是,如果您打算让用户从DataGrid添加/删除Employees或以其他方式修改Employees集合,您应该从{{1}更改Employees属性类型到List<Employee>,然后你的View(例如DataGrid)应该在新的Employee被移除或添加到ObservableCollection<Employee>集合时获取事件。

还有更多,如果您计划更改员工的属性,如Employees等,并希望通过视图注意这些更改(例如DataGrid在Eployee的FullName更改后更新相应的单元格)您的Employee类,反过来,也应该实现INotifyPropertyChanged - 但更好的是,你更不用说Employee是Model的一部分并从数据库加载并为Employee类创建单独的viewmodel。

我必须补充一点,如果您的任务只是在ViewModel构造上从数据库加载一次Employees,将它们转到View,只读,没有版本,更新或删除,您可以省略上面的所有麻烦,但我认为这是一种罕见的情况。