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:是的,我以前有一个版本使用了类型参数,后来我意识到我不需要它。