【问题标题】:How should I load one Entity with Child collection Properties in my ViewModel?我应该如何在我的 ViewModel 中加载一个具有子集合属性的实体?
【发布时间】:2011-11-03 03:57:31
【问题描述】:

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

因此,在 OnLoadComplete 上,我将返回的数据分配给 Employee,这是我的 VM 上的一个属性,并且还为 ComboBoxes 加载所有集合,例如 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" 为空,所以我得到一个异常。

其他人是如何做到这一点的,即等到 Employee 被加载?

【问题讨论】:

    标签: c# silverlight mvvm


    【解决方案1】:

    这样做的方法是使 SelectedDepartment 简单,然后在员工对象加载完成时对其进行更新。

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

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

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

    【讨论】:

      【解决方案2】:

      你可能想简单地替换

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

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

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

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

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

      【讨论】:

        【解决方案3】:

        请尝试:

        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];
        

        希望它有效。

        【讨论】:

          【解决方案4】:

          一种选择是采用“空对象模式”——拥有一个不代表任何内容的部门对象。

          所以,你可以替换

          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 数据时将所有值应用于属性。

          绑定会在前面工作,然后当数据进来的时候“null”处可以替换成合适的值。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-05-28
            • 1970-01-01
            • 1970-01-01
            • 2011-11-16
            • 1970-01-01
            • 2015-06-14
            • 2017-05-08
            • 2013-10-07
            相关资源
            最近更新 更多