我想在一个datacontext
中分配Combobox
和静态值。我试过这个,
this.courseList.DataContext = ldc.Courses.OrderBy(x => x.CourseID);
this.courseList.Items.Add("All");
this.courseList.Items.Add("Others");
但是,它会InvalidOperationException was Unhandeled
显示Items collection must be empty before using ItemsSource.
然后我尝试了这样,
this.courseList.Items.Add("All");
foreach (var items in ldc.Courses.OrderBy(x => x.CourseID))
{
this.courseList.Items.Add(items);
}
this.courseList.Items.Add("Others");
它就像这个图像
由于我在此
Combobox
的XAML设计中使用了ItemTemplate,因此它不会完全按照我的方式显示这两个值All
和Others
。
以下是ItemTemplate
<DataTemplate x:Key="CourseTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=CourseID}"/>
<TextBlock Text=" : "/>
<TextBlock Text="{Binding Path=CourseName}"/>
</StackPanel>
</DataTemplate>
...
<ComboBox Name="courseList" VerticalAlignment="Top" SelectionChanged="courseList_SelectionChanged" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}" ItemTemplate="{StaticResource CourseTemplate}"/>
我希望它根据DataTemplate查看数据库条目,并分别查看All
和Others
的简单字符串All
和Others
,如下图所示。
任何建议。谢谢。
答案 0 :(得分:2)
如错误所示,您只能直接使用ItemsSource或Items,而不能混合使用这两者。由于您实际上有两种不同类型的数据要以不同方式显示,因此您可以将它们全部添加到单个绑定集合中,然后让模板以不同方式呈现它们。第1步是构建单个集合:
this.courseList.ItemsSource = new object[] { "All" }.Concat(ldc.Courses.OrderBy(x => x.CourseID)).Concat(new[] { "Others" });
您现在在集合中有两种类型的数据:字符串和您认为是对象的对象。字符串将根据需要显示,无需任何额外工作,但您只需将DataTemplate应用于Course对象。最简单的方法就是用数据类型替换x:Key:
<DataTemplate DataType="{x:Type data:Course}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=CourseID}"/>
<TextBlock Text=" : "/>
<TextBlock Text="{Binding Path=CourseName}"/>
</StackPanel>
</DataTemplate>
其中数据xmlns对应于Course对象的命名空间。
接下来只需从ComboBox中删除ItemTemplate属性,就可以获得所需的内容。
如果您在同一范围内的其他位置也绑定了Course对象但希望它们以不同方式显示,则可以在本地范围内更多地定位DataType模板(即Grid.Resources)或在ComboBox上使用DataTemplateSelector。
答案 1 :(得分:1)
由于ldc.Courses
设置为DataContext
,并且您有ItemsSource="{Binding}"
,这意味着组合框直接绑定到您的集合。当您尝试添加字符串时,这会产生问题,因为现在集合同时包含字符串和课程对象。
我认为这可能是最容易理解的解决方案。从第二种方法开始:
this.courseList.Items.Add("All");
foreach (var items in ldc.Courses.OrderBy(x => x.CourseID))
{
this.courseList.Items.Add(items.CourseID.ToString() + " : " + items.CourseName);
}
this.courseList.Items.Add("Others");
这会使你的组合框绑定到一个简单的字符串列表而不是对象,所以只要你在后台不需要其他信息,这将更容易消化,如果没有尝试混合的其他答案之一字符串和对象进入同一个集合。这也意味着您无需设置DataContext
,ItemsSource
或DataTemplate
,因此请将其全部删除。
如果您希望保持模板添加更多控件,您可能还想查看其他一些答案。另一种方法是在您的课程对象上创建一个父类,它也可以采用更一般的ALL
和OTHER
个案例,并在它们周围创建实际对象可能是最灵活的。这样,您就不会以字符串和对象的集合结束,这将导致您在操作集合时必须创建特殊的代码集。
答案 2 :(得分:1)
您可以使用ItemTemplate与转换器结合使用来解决此问题。
模板:
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource ComboBoxItemConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
转换器:
public class ComboBoxItemConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is Courses)
{
var course = value as Courses;
return course.CourseID + " : " + course.CourseName;
}
else
{
return value.ToString();
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}