2016-05-26 35 views
1

我想从多个ComboBoxes填充特定记录的数据。我可以让他们中的一个正常工作,但我认为一个概念错误阻止了我获得第二个正确的工作。我已经搜索了SelectedItem,SelectedValue和SelectedIndex的各种线程,并在提供指导后尝试了我的代码。显然我做错了什么,但不知道是什么。我非常了解我从互联网上学到的所有东西。MVVM组合框SelectedIndex与SelectedItem

我正在使用实体框架6数据库第一个数据模型。我有一个表(主),它有一个外键链接到Shift和另一个人事表。 Shift表具有ShiftId(PK)字段,其Identity设置为true,Shift仅是一个字符串。人事表具有Identity设置为false的PersonnelId(PK)(我从别处手动填充ID)以及名字和姓氏字段。

我的项目需要的流程是:1)获取当前记录,2)填充Shift组合框,3)显示与当前记录相关联的班次,4)填充人员组合框,5)显示关联的人员与当前记录,6)保存对记录的任何更改(通过为任一组合框选择不同的值而建立的更改)。

我的ViewModel正在使用INotifyPropertyChanged,我想我已经实现了这个,因为Shift ComboBox是有效的。

1)获取所需的记录正常工作。然后将其存储为“CurrentRecord”

2)填充Shift组合框工作正常。
在我型号我:

private ICollection<Gen_All_Shift> shiftList; 
    public ICollection<Gen_All_Shift> GetShiftList() 
    { 
     shiftList = context.Gen_All_Shift.OrderBy(p => p.ShiftId) 
              .ToArray(); 
     return shiftList; 
    } 

在我视图模型我有:

public ICollection<Gen_All_Shift> ShiftList 
    { 
     get { return context.GetShiftList(); } 
    } 

    private Gen_All_Shift selectedShift; 
    public Gen_All_Shift SelectedShift 
    { 
     get { return selectedShift; } 
     set 
     { 
      if (value != selectedShift) 
      { 
       selectedShift = value; 
       NotifyPropertyChanged("SelectedShift"); 
      } 
     } 
    } 

然后XAML是:

 <ComboBox x:Name="cboShift" 
      ItemsSource="{Binding ShiftList}" 
      DisplayMemberPath="Shift" 
      SelectedIndex="{Binding CurrentRecord.ShiftIdFk, 
          UpdateSourceTrigger=PropertyChanged}" /> 

3)显示目前轮班工作只要我具有绑定到SelectedIndex。如果我使用SelectedItem或SelectedValue,则在加载屏幕时组合框为空。 (我也尝试绑定到SelectedShift.ShiftId,但没有给我想要的结果。)SelectedIndex将允许我改变选择,并允许我正确地保存对实际数据库的更改。我不知道我在做什么错误,防止SelectedItem或SelectedValue工作。不理解这是什么导致我有问题与我相信人员组合框。

4)填充人员组合框的作品。

在我型号我:

private ICollection<Personnel_All_PersonnelList> personnelList; 
    public ICollection<Personnel_All_PersonnelList> GetPersonnelList() 
    {    
      personnelList = context.Personnel_All_PersonnelList.Where(p=>p.Active == true) 
                   .OrderBy(p => p.LastName) 
                   .ThenBy(p => p.FirstName) 
                   .ToArray(); 
      return personnelList; 
    } 

在我视图模型我:

public ICollection<Personnel_All_PersonnelList> PersonnelList 
    { 
     get 
     { 
       return context.GetPersonnelList(); 
     } 
    } 

    private Personnel_All_PersonnelList selectedPerson; 
    public Personnel_All_PersonnelList SelectedPerson 
    { 
     get { return selectedPerson; } 
     set 
     { 
      if (value != selectedPerson) 
      { 
       selectedPerson = value; 
       NotifyPropertyChanged("SelectedPerson"); 
      } 
     } 
    } 

然后在我的XAML我:

<ComboBox x:Name="cboTechnician" 
      ItemsSource="{Binding PersonnelList}" 
      DisplayMemberPath="LastName" 
      SelectedIndex="{Binding CurrentRecord.PersonnelIdFk, 
          UpdateSourceTrigger=PropertyChanged}" /> 

5)无论我尝试哪种方式(SelectedIndex,SelectedItem,SelectedValue),显示当前人员都不起作用。我猜这是因为SelectedIndex不能正常工作,原因是索引号与PersonnelId没有正确对齐,所以系统不知道哪一个被选中。

6)如果我只更改了Shift,保存对记录的更改将有效。如果我在Personnel ComboBox中选择一个人并尝试保存,则会收到系统空例外。我认为这是由于阻止SelectedIndex与人员组合框一起工作的相同问题引起的。

我想如果有人可以指出我正确的方向,为什么我无法获得对SelectedItem工作正常的绑定,我将能够弄清楚如何修复Personnel组合框。

回答

1

您尝试的第一件事实际上是正确的,但有几件事让您失望。

例如:

get { return context.GetShiftList(); } 

通常,这是不是一个好主意。任何人调用此属性将调用数据库调用每次这将伤害性能,并不需要。

一个更好的想法是不是调用一个方法来负载ShiftList财产,像这样的:

public void ReloadShiftList() 
{ 
    //TODO: Your logic here 

    ShiftList = ... 
} 

注:一定要在你的ShiftList财产实施INotifyPropertyChanged以更新每当此属性发生更改时查看。

至于你的ComboBox,与SelectedItem绑定肯定是首选的方法。在第一次加载时,所选项目为空白的原因是因为SelectedShift被设置为空。要解决这个问题,只需在加载ShiftList后设置SelectedShift即可。

ShiftList = ... 
SelectedShift = ShiftList.FirstOrDefault(); 

通过设置SelectedShiftShiftList.FirstOrDefault(),你将保证会有总是ComboBox选择的东西(除非有在ShiftList没有任何项目)。

最后,你的绑定是这样的:

<ComboBox ItemsSource="{Binding ShiftList}" 
      SelectedItem="{Binding SelectedShift}" 
      ... /> 
0

@Mike Eason - 谢谢你,给了我我需要的东西!

视图模型的转变,现在看起来是这样的:

private ICollection<Gen_All_Shift> shiftList; 
    public ICollection<Gen_All_Shift> ShiftList 
    { 
     get { return shiftList; } 
     set { shiftList = value; NotifyPropertyChanged("ShiftList"); } 
    } 

    private Gen_All_Shift selectedShift; 
    public Gen_All_Shift SelectedShift 
    { 
     get { return selectedShift; } 
     set { selectedShift = value; NotifyPropertyChanged("SelectedShift"); } 
    } 

    public void LoadShiftList() 
    { 
     ShiftList = context.GetShiftList(); 
     SelectedShift = ShiftList.Where(p => p.ShiftId == CurrentRecord.ShiftIdFk) 
           .FirstOrDefault(); 
    } 

随着到LoadShiftList()的调用在视图模型构造。

然后XAML现在作为目标的绑定集到的SelectedItem:

 <ComboBox x:Name="cboShift" 
      ItemsSource="{Binding ShiftList}" 
      DisplayMemberPath="Shift" 
      SelectedItem="{Binding SelectedShift}" /> 

此前我一直试图设置SelectedShift.ShiftId == CurrentRecord.ShiftIdfk。这一直给我一个空例外。指出使用.FirstOrDefault()让我回到正确的道路上。再次感谢。