2010-06-07 65 views
4

我使用MVVM(MVVM光工具包),并具有在其上暴露的对象的列表视图模型的特性。这些对象包含两个属性,这两个属性都与缩写和描述相关。我希望ComboBox将配对公开为“缩写 - 描述”。如果我使用数据模板,它很容易实现。WPF组合框结合到非字符串对象

我有代表作为选择应显示该对象的视图模型的另一个属性 - ComboBox中选择的项目。我将ItemsSource绑定到列表,因为它代表了可用选择的范围,并试图将SelectedItem绑定到此对象。我试图弄清楚为什么我无法实现它的工作,并且感觉更像是一个小时内的欺诈。

在试图了解为什么这个作品,我创造了同样的做法只是一个字符串列表,以及所选择的字符串。这工作完美。所以,这显然与打字有关......也许是选择平等的东西?或者它可能与数据模板有关?

这里是XAML:

<Window x:Class="MvvmLight1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" 
     Height="300" 
     Width="300" 
     DataContext="{Binding Main, Source={StaticResource Locator}}"> 

    <Window.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="Skins/MainSkin.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 
      <DataTemplate x:Key="DataTemplate1"> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock TextWrapping="Wrap" Text="{Binding CourtCode}"/> 
        <TextBlock TextWrapping="Wrap" Text=" - "/> 
        <TextBlock TextWrapping="Wrap" Text="{Binding CourtDescription}"/> 
       </StackPanel> 
      </DataTemplate> 
     </ResourceDictionary> 
    </Window.Resources> 

    <Grid x:Name="LayoutRoot"> 
     <ComboBox x:Name="cmbAbbrevDescriptions" Height="35" Margin="25,75,25,25" VerticalAlignment="Top" ItemsSource="{Binding Codes}" ItemTemplate="{DynamicResource DataTemplate1}" SelectedItem="{Binding selectedCode}" /> 
     <ComboBox x:Name="cmbStrings" Height="35" Margin="25" VerticalAlignment="Top" ItemsSource="{Binding strs}" SelectedItem="{Binding selectedStr}"/> 
    </Grid> 
</Window> 

而且,如果有帮助,这里是视图模型:

using GalaSoft.MvvmLight; 
using MvvmLight1.Model; 
using System.Collections.Generic; 

namespace MvvmLight1.ViewModel 
{ 
    public class MainViewModel : ViewModelBase 
    { 
     public const string CodesPropertyName = "Codes"; 
     private List<Court> _codes = null; 
     public List<Court> Codes 
     { 
      get 
      { 
       return _codes; 
      } 

      set 
      { 
       if (_codes == value) 
       { 
        return; 
       } 

       var oldValue = _codes; 
       _codes = value; 

       // Update bindings and broadcast change using GalaSoft.Utility.Messenging 
       RaisePropertyChanged(CodesPropertyName, oldValue, value, true); 
      } 
     } 

     public const string selectedCodePropertyName = "selectedCode"; 
     private Court _selectedCode = null; 
     public Court selectedCode 
     { 
      get 
      { 
       return _selectedCode; 
      } 

      set 
      { 
       if (_selectedCode == value) 
       { 
        return; 
       } 

       var oldValue = _selectedCode; 
       _selectedCode = value; 

       // Update bindings and broadcast change using GalaSoft.Utility.Messenging 
       RaisePropertyChanged(selectedCodePropertyName, oldValue, value, true); 
      } 
     } 

     public const string strsPropertyName = "strs"; 
     private List<string> _strs = null; 
     public List<string> strs 
     { 
      get 
      { 
       return _strs; 
      } 

      set 
      { 
       if (_strs == value) 
       { 
        return; 
       } 

       var oldValue = _strs; 
       _strs = value; 

       // Update bindings and broadcast change using GalaSoft.Utility.Messenging 
       RaisePropertyChanged(strsPropertyName, oldValue, value, true); 
      } 
     } 

     public const string selectedStrPropertyName = "selectedStr"; 
     private string _selectedStr = ""; 
     public string selectedStr 
     { 
      get 
      { 
       return _selectedStr; 
      } 

      set 
      { 
       if (_selectedStr == value) 
       { 
        return; 
       } 

       var oldValue = _selectedStr; 
       _selectedStr = value; 

       // Update bindings and broadcast change using GalaSoft.Utility.Messenging 
       RaisePropertyChanged(selectedStrPropertyName, oldValue, value, true); 
      } 
     } 


     /// <summary> 
     /// Initializes a new instance of the MainViewModel class. 
     /// </summary> 
     public MainViewModel() 
     { 
      Codes = new List<Court>(); 

      Court code1 = new Court(); 
      code1.CourtCode = "ABC"; 
      code1.CourtDescription = "A Court"; 

      Court code2 = new Court(); 
      code2.CourtCode = "DEF"; 
      code2.CourtDescription = "Second Court"; 

      Codes.Add(code1); 
      Codes.Add(code2); 


      Court code3 = new Court(); 
      code3.CourtCode = "DEF"; 
      code3.CourtDescription = "Second Court"; 
      selectedCode = code3; 

      selectedStr = "Hello"; 
      strs = new List<string>(); 
      strs.Add("Goodbye"); 
      strs.Add("Hello"); 
      strs.Add("Ciao"); 

     } 
    } 
} 

这里是被曝光的可笑的小事类:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace MvvmLight1.Model 
{ 
    public class Court 
    { 
     public string CourtCode { get; set; } 

     public string CourtDescription { get; set; } 
    } 
} 

谢谢!

回答

1

运行时不知道,码2和CODE3应该是平等的。

看到http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx

public override bool Equals(object o) 
{ 
    var court = o as Court; 
    if(court == null) 
     return false; 
    return CourtCode == court.CourtCode; 
} 
+0

太棒了!它与WPF,绑定等无关。这只是类型平等的一个愚蠢的错误。多谢! – 2010-06-07 07:36:50

0

你SelectedCode CODE3是不存在的代码集合。添加它,以便选择将按预期工作。

你selectedStr工作,因为它是收藏。 [strs.Add("Hello");]

+0

或覆盖法院类的equals方法,还记得重写GetHashCode方法。 – Oggy 2010-06-07 06:28:48

+0

对,代码集合中不存在代码3。但它相当于code2 ......这就是我错过了这条船的地方。我试图说“所有这些可能的类型,选择一个匹配这个类型的类型”。 – 2010-06-07 07:00:45

+0

@Oggy - 如果我明白,你说ComboBox试图设置选定的项目,但它不能确定对象实例之间的相等性? – 2010-06-07 07:02:36