【问题标题】:WPF and Creating Objects and why aren't certain properties being set? (MVVM, EF)WPF 和创建对象,为什么不设置某些属性? (MVVM, 英孚)
【发布时间】:2014-10-14 04:29:53
【问题描述】:

我不确定为什么我在 XAML 中定义的属性没有在 ViewModel 中公开?这是我当前的应用程序:有一个 WPF 4.5 项目,使用 MVVM 模式和 Entity Framework 6.0。

当我尝试在 Save() 上创建一个新对象时,比如 Employee,我在 EmployeeViewModel 中用一些默认值实例化一个 Employee 对象,例如:

C#

public class EmployeeViewModel
{

    private Employee _employee;
    public Employee Employee
    {
        get
        {
            return _employee;
        }
        set
        {
            _employee = value;
            RaisePropertyChanged("Employee");
        }
    }

    public EmployeeViewModel()
    {
        Employee = new Employee();
        Employee.HireDate = DateTime.Now;
            ...
    }



} 

XAML:

...
<TextBox Text="{Binding Employee.FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding Employee.LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding Employee.Salary, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
...

我从上面的 XAML 中知道路径,例如正在为这些属性找到“Employee.FirstName”,因为我没有收到警告,指出它无法弄清楚 Employee 是什么。仅供参考,我为这个 XAML 设置了 DataContext,如下所示:

DataContext="{Binding Path=EmployeeViewModel, Source={StaticResource Locator}}">

虽然我没有在 ViewModel 中显式设置 FirstName、LastName 等 Employee 属性,但它们不应该仍然通过 ViewModel 中 Employee 的公共属性来设置吗?

我还在 Employee 类中定义的属性上设置了一些断点,该类位于定义我的 Entity Framework Code First 并且没有命中的位置。

因此,当我输入数据然后单击“保存”按钮时,该表单会调用 EmployeeViewModel 中的 Save 方法,该方法将 Employee 对象作为参数,我可以看到 Employee 对象没有任何属性假设来自 XAML 的集合,我看到填充的唯一属性是我最初通过 ViewModel 的构造函数设置的属性。

我错过了什么?


编辑 1:

这是我的 Save 方法,这是我调查 Employee 对象的地方,它具有与通过 EmployeeViewModel 的构造函数实例化时相同的属性:

public void Save()
{
    AddEmployee(Employee);
}

我很确定它是构造函数中的同一个 Employee 对象,因为上面有时间戳。


编辑 2:

我的 Employee 类是在一个基本上是 EF Code First 项目的项目中定义的。这是我课堂的一部分:

 [Table("Employee")]
 public partial class Employee
 {
     public Employee()
     {
         Projects = new ICollection<Project>();
     }

     public int EmpId{ get; set; }

     [StringLength(50)]
     public string FirstName { get; set; }

     ...

【问题讨论】:

  • 来自哪里的Employee 对象是命令的参数?您确定它与EmployeeViewModel 成员的实例相同吗?
  • @Andy:我添加了一个部分,编辑 1,谢谢。
  • 您是否在 Employee 类中实现了 INotifyPropertyChanged? AddEmployee 函数长什么样子?
  • @Matan:我添加了一个部分,编辑 2,希望对您有所帮助。

标签: c# wpf xaml mvvm


【解决方案1】:

在您的 Employee 类中实现 INotifyPropertyChanged:(绑定在您的 Employee 的属性上,属性更新时不会收到通知)

    [Table("Employee")]
    public partial class Employee : INotifyPropertyChanged
    {
        public Employee()
        {
            Projects = new ICollection<Project>();
        }

        private int _empId;
        public int EmpId 
        {
            get
            {
                return _empId;
            }
            set
            {
                _empId = value;
                NotifyPropertyChanged("EmpId");
            }
        }

        private string _firstName;
        [StringLength(50)]
        public string FirstName
        {
            get
            {
                return _firstName;
            }
            set
            {
                _firstName = value;
                NotifyPropertyChanged("FirstName");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

更新:

尝试阅读这篇文章,它可能有一种在 WPF 中绑定数据库对象的本机方式。 here

【讨论】:

  • 我假设这些 EF 类应该尽可能多地使用 POCO,即例如没有 INotifyPropertyChanged?尽管如此,我会继续执行您的建议并报告回来,谢谢!
  • 如果你想保持 Employee 类为 POCO,你可以使用另一个层来创建另一个名为“EmployeeView”的类,或者它的目的是呈现一个 Employee 对象,它会观察一个 Employee 实例,并且绑定将应用于他。但还有很多工作要做。
  • 此外,如果您不想在视图模型中完成复制每个字段的所有工作,那么可以自动向所有成员添加更改通知。基本思想是您将您的成员标记为虚拟,然后使用 Castle Dynamic Proxy 之类的东西为您注入更改通知。我还没有将它与 EF 一起使用,但我确实将它用于 NHibernate,并且效果很好。
  • @MarkFeldman,一个非常好的主意:Castle Dynamic Proxy,谢谢!
猜你喜欢
  • 2011-03-23
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-22
  • 2021-04-11
  • 2012-11-25
  • 1970-01-01
相关资源
最近更新 更多