我应该如何在ViewModel中加载一个带有子集合属性的实体?

时间:2011-11-03 03:57:31

标签: c# silverlight mvvm

我有一个绑定到ViewModel(VM)的自定义数据输入表单。数据输入表格假设显示用户输入员工数据的字段,即每个表格1个员工。 EmployeeViewModel从Web服务(如一个Employee(用于更新)和许多集合)加载大量数据。这些集合包括“部门”,例如员工属于许多部门之一,“监督员”,例如,员工被分配给主管,依此类推。所以,在我的VM的构造函数中,我从服务中获取FetchData(),我必须等到它完成。

因此,在OnLoadComplete上,我将返回的数据分配给Employee,这是我的VM上的属性,并且还为ComboBox加载所有集合,如Departments。

VM上的其他属性在加载b / c上呈现NullExceptions,它们如下所示:

private Department_selectedDepartment;
public Department SelectedDepartment
{
   get
      { return this.Employee.Department; }          **// where error occurs**
   set
      {
          _selectedDepartment = value;
          this.Employee.Department = value;
          OnPropertyChanged("SelectedDepartment");
      }
}

在我的XAML中,我有收藏品和他们的“选定...” - 部分如此:

<ComboBox
    ItemsSource="{Binding Departments, Mode=OneWay}"
    SelectedItem="{Binding SelectedDepartment, Mode=TwoWay}" />

当SelectedDepartment的getter在VM加载时命中,它表示this.Employee“为null,所以我得到一个例外。

其他人如何做到这一点,即等到员工加载?

4 个答案:

答案 0 :(得分:3)

这样做的方法是使SelectedDepartment变得简单,然后在employee对象加载完毕后更新它。

private Department _selectedDepartment;
public Department SelectedDepartment
{
   get
      { return _selectedDepartment; } 
   set
      {
          _selectedDepartment = value;
          OnPropertyChanged("SelectedDepartment");
      }
}

然后,在您的员工完成加载后,选择正确的部门

SelectedDepartment = Departsments.Where(department=> department.ID == Employee.Department.ID ).First();

答案 1 :(得分:2)

您可能只想替换

 get
  { return this.Employee.Department; }          **// where error occurs**

 get { return Employee == null? null: Employee.Department; }    

(或者更好的代码,比如没有三元运算符)

当没有加载任何内容时,在组合框中选择任何内容没有多大意义,错误不是因为你绑定到null,而是因为你试图从null引用获得Department。

有人可能会争论你决定从viewmodel构造函数中获取东西吗? (如果我理解正确的话)但我猜这超出了这个问题的范围。

答案 2 :(得分:1)

一种选择是采用&#34; null对象模式&#34; - 有一个不代表任何东西的Department对象。

所以,你可以替换

private Department _selectedDepartment;
public Department SelectedDepartment
{
    get { return this.Employee.Department; }

private Department _selectedDepartment = new Department { Name = string.Empty };
public Department SelectedDepartment
{
    get { return _selectedDepartment; }

您需要某种方法,在收到Employee数据时将所有值应用于属性。

绑定将在前面工作,然后当数据进入&#34; null&#34;可以用适当的值替换部门。

答案 3 :(得分:1)

请尝试:

private Department _selectedDepartment;
public Department SelectedDepartment
{
   get
      { return _selectedDepartment;}   //return this.Employee.Department; 
   set
      {
          _selectedDepartment = value;
                                                               //this.Employee.Department = value;
          OnPropertyChanged("SelectedDepartment");
      }
}

然后从服务加载Employee,并加载所有集合,如Departments .... 最后为ComboBox绑定添加这些行:

Departments = new List<Department>(); //feed the collection by service calling result for ComboBox DataSource. 
SelectedDepartment = Employee.Department; //or, SelectedDepartment = Departments[0];

希望它有效。