2014-01-21 39 views
0

我正在尝试将一个空的项目与一个组合框绑定。为此,我正在使用CompositeCollection,因为我已经阅读了许多问题。Combobox Empty Item

目前工作正常。然而,使用复合集合会混淆我所拥有的分组。要么我得到组合框中的空白,要么我得到分组。我希望两者都可用。

这里是我一直在玩的示例代码:

的XAML

<Window.Resources> 
    <local:CourseConverter x:Key="CourseConverter" /> 
    <DataTemplate DataType="{x:Type local:Course}"> 
     <TextBlock Text="{Binding Path=CourseName}" /> 
    </DataTemplate> 
    <CollectionViewSource x:Key="CoursesCVS" Source="{Binding Courses}"> 
     <CollectionViewSource.GroupDescriptions> 
      <PropertyGroupDescription PropertyName="Major" /> 
     </CollectionViewSource.GroupDescriptions> 
    </CollectionViewSource> 
</Window.Resources> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="0.2*"/> 
     <RowDefinition Height="Auto "/> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="*"/> 
    </Grid.RowDefinitions> 
    <TextBlock Text="Select Course" Grid.Row="1" Margin="15,5,0,5" Width="200" /> 
    <ComboBox Grid.Row="2" Width="200" Margin="15,5,0,5" 
       ItemsSource="{Binding Source={StaticResource CoursesCVS}}" 
       SelectedItem="{Binding SelectedCourse, Converter={StaticResource CourseConverter}}"> 
     <ComboBox.GroupStyle> 
      <GroupStyle> 
       <GroupStyle.HeaderTemplate> 
        <DataTemplate> 
         <TextBlock Text="{Binding Name}"/> 
        </DataTemplate> 
       </GroupStyle.HeaderTemplate> 
      </GroupStyle> 
     </ComboBox.GroupStyle> 
     <!--<ComboBox.ItemsSource> 
      <CompositeCollection> 
       <ComboBoxItem Content="" /> 
       <CollectionContainer Collection="{Binding Source={StaticResource CoursesCVS}}" /> 
      </CompositeCollection> 
     </ComboBox.ItemsSource>--> 
    </ComboBox> 
    <TextBlock Text="{Binding SelectedCourse.CourseName}" Grid.Row="3" Margin="15,5,0,5" Width="200" /> 
</Grid> 

视图模型和支持类:

public class Course 
{ 
    public int CourseID { get; set; } 
    public string CourseName { get; set; } 
    public string Major { get; set; } 
} 

public class MainWindowViewModel : INotifyPropertyChanged 
{ 
    public MainWindowViewModel() 
    { 
     _courses = new List<Course>(); 
     _courses.Add(new Course { CourseID = 1, CourseName = "Math 107", Major = "Math" }); 
     _courses.Add(new Course { CourseID = 1, CourseName = "Biology 110", Major = "Biology" }); 
     _courses.Add(new Course { CourseID = 1, CourseName = "Chemistry 123", Major = "Chemistry" }); 
     _courses.Add(new Course { CourseID = 1, CourseName = "Spanish 112", Major = "Biology" }); 
     _courses.Add(new Course { CourseID = 1, CourseName = "Molecular 114", Major = "Biology" }); 
    } 

    private List<Course> _courses; 

    public List<Course> Courses 
    { 
     get { return _courses; } 
     set { _courses = value; OnPropertyChanged(); } 
    } 

    private Course _selectedCourse; 

    public Course SelectedCourse 
    { 
     get { return _selectedCourse; } 
     set { _selectedCourse = value; OnPropertyChanged(); } 
    } 


    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged([CallerMemberName]string propertyName = "") 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

} 

public class CourseConverter : IValueConverter 
{ 

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return value; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value is Course) 
      return value; 
     else 
      return null; 
    } 
} 

有没有,我很想念使它的东西与分组一起工作。为了移除分组,我删除内联的ItemSource声明并使用注释的代码。这显示了空白。

+1

不认为''CompositeCollection'甚至可以直接支持排序/过滤/分组,直接处理子类或自己处理东西。难道你不能只在虚拟机集合中添加一个空项目来实现你的目标,而不是完全不使用CompositeCollection?这样,只有虚拟机中的集合才具有虚拟元素,而不是您的模型,如果您想要更好地分离,可以使用接口实现您的'ItemSource',并让Dummy项和'Course'实现该接口以轻松区分它们后来。 – Viv

回答

1

在WPF中,我们使用数据项目,而不是UI元素。我们声明DataTemplate s来定义我们的数据项在任何UI容器中的外观。使用这种方法,我们让框架负责显示用户界面,并专注于数据。所以,以显示WPF空UI元素,你只需要一个空的数据项添加到您的收藏,让DataTemplate做的工作:

_courses.Add(new Course()); 

这将简单地呈现为一个空的项目,因为它有没有数据要显示在任何数据绑定控件中。因此,如果您只想显示一个值,请尝试在ComboBox.ItemTemplate属性中声明DataTemplate,或者只需将DisplayMemberPath设置为相关的Course属性。