C# 填充组合框时出现问题
我有一个这样的模型课:C# 填充组合框时出现问题,c#,.net,wpf,xaml,mvvm,C#,.net,Wpf,Xaml,Mvvm,我有一个这样的模型课: public class AttributesModel { public SortOrder SortBy { get; set; } public enum SortOrder { Unsorted, Ascending, Descending } public AttributesModel(string
public class AttributesModel
{
public SortOrder SortBy { get; set; }
public enum SortOrder
{
Unsorted,
Ascending,
Descending
}
public AttributesModel(string field)
{
Field = field;
}
}
以及一个DataGrid,其中包含一个组合框作为列之一,如下所示:
<DataGridTemplateColumn Width="Auto" IsReadOnly="False" Header="Order">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Path=AttributesModel}" DisplayMemberPath="SortBy" SelectedValuePath="SortBy" SelectedValue="{Binding Path=AttributesModel}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
包含DataGrid的类还具有以下构造函数:
DataContext = this;
itemsSource = new ObservableCollection<AttributesModel>(parentDatabaseTable.ListFields.Select(f => new AttributesModel(f)));
DataContext=this;
itemsSource=new ObservableCollection(parentDatabaseTable.ListFields.Select(f=>new AttributesModel(f));
出于某种原因,除了combobox之外,我的DataGrid中的所有字段都在填充。请注意,为了简单易读,我没有在模型类中包含其他字段的代码,也没有在DataGrid中包含列的代码。除了combobox列之外,它们都已成功填充。有什么想法吗?一个
项目资源必须是一个集合。您的AttributeModel
不是一个集合
如果要绑定枚举的选项,我以前使用过:
public class EnumWrapper<T> where T:struct
{
private List<T> values;
public List<T> Values
{
get { return values; }
set { values = value; }
}
public EnumWrapper()
{
// Note: Annoyingly, you can't restrict T to an Enum, so we have to check at runtime!
Type type = typeof(T);
if (!type.IsEnum)
{
throw new ArgumentException("Type must be an enum");
}
Array a = Enum.GetValues(type);
values = a.Cast<T>().ToList();
}
}
ItemsSource
必须是一个集合。您的AttributeModel
不是一个集合
如果要绑定枚举的选项,我以前使用过:
public class EnumWrapper<T> where T:struct
{
private List<T> values;
public List<T> Values
{
get { return values; }
set { values = value; }
}
public EnumWrapper()
{
// Note: Annoyingly, you can't restrict T to an Enum, so we have to check at runtime!
Type type = typeof(T);
if (!type.IsEnum)
{
throw new ArgumentException("Type must be an enum");
}
Array a = Enum.GetValues(type);
values = a.Cast<T>().ToList();
}
}
虽然上面Matt的答案在理论上是可行的,但如果您不想制作包装器,可以使用这个基于xaml的代码。它需要将Enum
包含在根命名空间中,而不是嵌套在类中,但除此之外,您只需在Enum
上创建一个ObjectDataProvider
StaticResource
并将其绑定到组合框中即可
<UserControl x:Class="TestApplication.DatabaseTable"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:TestApplication"
mc:Ignorable="d" Width="Auto" Height="Auto">
<UserControl.Resources>
<ObjectDataProvider ObjectType="{x:Type sys:Enum}" MethodName="GetValues" x:Key="SortOrderProvider">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:SortOrder" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</UserControl.Resources>
<DataGrid x:Name="grid" ItemsSource="{Binding ItemsSource}" AutoGenerateColumns="True">
<DataGrid.Columns>
<DataGridComboBoxColumn Header="Order" ItemsSource="{Binding Source={StaticResource SortOrderProvider}}" SelectedItemBinding="{Binding SortBy, Mode=TwoWay}"/>
</DataGrid.Columns>
</DataGrid>
</UserControl>
虽然上面Matt的答案在理论上应该是可行的,但如果您不想制作包装器,可以使用此基于xaml的代码。它需要将Enum
包含在根命名空间中,而不是嵌套在类中,但除此之外,您只需在Enum
上创建一个ObjectDataProvider
StaticResource
并将其绑定到组合框中即可
<UserControl x:Class="TestApplication.DatabaseTable"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:TestApplication"
mc:Ignorable="d" Width="Auto" Height="Auto">
<UserControl.Resources>
<ObjectDataProvider ObjectType="{x:Type sys:Enum}" MethodName="GetValues" x:Key="SortOrderProvider">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:SortOrder" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</UserControl.Resources>
<DataGrid x:Name="grid" ItemsSource="{Binding ItemsSource}" AutoGenerateColumns="True">
<DataGrid.Columns>
<DataGridComboBoxColumn Header="Order" ItemsSource="{Binding Source={StaticResource SortOrderProvider}}" SelectedItemBinding="{Binding SortBy, Mode=TwoWay}"/>
</DataGrid.Columns>
</DataGrid>
</UserControl>
因此,看起来您正在将组合框绑定到一个属性AttributesModel
,该属性不是IEnumerable
,对吗?实际上是其中包含的枚举。我还有其他字段,它可以毫无问题地绑定到这些字段。因此,看起来您正在将组合框
绑定到一个属性AttributesModel
,该属性不是IEnumerable
,对吗?它实际上包含的枚举。我还有其他字段,它可以毫无问题地绑定到这些字段。那么我为组合框设置的属性呢?这些是有效的吗?@DotNET:我已经根据答案进行了更新,假设DataContext已经是AttributesModel
类的一个实例,SortOptions
是EnumWrapper
@MattBurland类型的属性,我认为EnumWrapper构造函数代码中有输入错误。它不接受任何类型参数,但您的示例传入了它。我还猜你是想写“烦人的是,你不能限制T…”:)+1来完成这项工作。@Maverik:是的,我以前的版本使用了一个类型参数,然后我意识到我不需要它。我为ComboBox设置的属性呢?这些是有效的吗?@DotNET:我已经根据答案进行了更新,假设DataContext已经是AttributesModel
类的一个实例,SortOptions
是EnumWrapper
@MattBurland类型的属性,我认为EnumWrapper构造函数代码中有输入错误。它不接受任何类型参数,但您的示例传入了它。我还猜你是想写“烦人的是,你不能限制T…”:)+1来完成这项工作。@Maverik:是的,我以前有一个版本使用了类型参数,后来我意识到我不需要它。