DataGridViewComboBoxColumn不允许我从列表中选择对象

时间:2011-11-01 13:11:27

标签: c# .net datagridview

我有一个DataGridView,允许用户将新对象添加到列表中。其中一个重要部分是从用户可定义的列表中选择类型。

我正在定义这样的列:

this.DataGridView.Columns.Add(new DataGridViewComboBoxColumn
                              {
                                  Name = "Resource",
                                  DataPropertyName = "Resource",
                                  DataSource = new BindingSource { DataSource = this.Document.Resources },
                                  ValueType = typeof(Resource),
                                  DisplayMember = "Name"
                              });

然后我将DataGridView的DataSource设置为UserResources列表:

BindingList<UserResource> relatedResources = new BindingList<UserResource>(this.User.ResourcesRequired);
this.DataGridView.DataSource = relatedResources;

Resource类布局如下所示:

public class Resource
{
    public string Name { get; set; }
    public string Description { get; set; }
    public int InitialLevel { get; set; }
}

UserResource类如下所示:

public class UserResource
{
    public Resource Resource { get; set; }
    public int CurrentLevel { get; set;
}

User类如下所示:

public class User
{
    public string Name { get; set; }
    public IEnumerable<UserResource> Resources { get; set; }
}

我可以看到可用资源类型的列表,但是DataGridViewComboBoxCell中选择的项目不会保持选中状态。选择项目后,当我移动到下一个字段时,DataGridViewComboBoxCell将自行清除。

该行中的其他字段将写入我的新UserResource实例,但不会保存Resource引用,并且该属性在新的UserResource实例上保持为null。

如果人们想知道,我根本不使用任何类型的对象关系映射器或任何类型的数据库层。内存中的所有对象都写入XML文档并从中读取。

我真的不确定如何从这里继续调试此问题。有人有什么建议吗?

3 个答案:

答案 0 :(得分:2)

好的,我做了一些改变。现在它一开始工作正常。将资源类更改为:

    public class Resource
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public int InitialLevel { get; set; }
//added by dx
        public new string ToString()
        {
            return Name;
        }
    }

为Grid组合框创建新类:

    public class  ComboSource
    {
        public string Name
        {
            get
            {
                if (SourceValue != null)
                    return SourceValue.ToString();
                return string.Empty;
            }
        }
        public Resource SourceValue{ get; set; }

    }

样本用法:

       private List<ComboSource> resources = new List<ComboSource>();
            this.resources.Add(new ComboSource() { SourceValue = new Resource() { Name = "rs1", Description = "a"} });
            this.resources.Add(new ComboSource() { SourceValue = new Resource() { Name = "rs2", Description = "b" } });
            this.resources.Add(new ComboSource() { SourceValue = new Resource() { Name = "rs3", Description = "c" } });

        this.dataGridView1.Columns.Add(new DataGridViewComboBoxColumn
        {
            Name = "Resource",
            DataPropertyName = "Resource",
            ValueMember = "SourceValue",
            DataSource = new BindingSource { DataSource = this.resources },
            ValueType = typeof(Resource),
            DisplayMember = "Name"
        });

答案 1 :(得分:1)

我认为问题不在于这种控制。您可以选择该项目。正如您所说,当您在表单上移动时,项目将被清除。

这意味着还有其他来源正在对此控件进行验证并决定清除它。请查找代码的其他部分或挂钩可能正在修改所选值的更改事件。

我愿意提供更多帮助,但我需要查看完整代码,如果您愿意分享,我的电子邮件地址就在我的个人资料中。

答案 2 :(得分:0)

                    <telerik:DataFormComboBoxField Grid.Row="0" Grid.Column="2" Label="Time Zone:" LabelPosition="Above">
                    <telerik:RadComboBox SelectedValue="{Binding TimeZoneID, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" 
                                        ItemTemplate="{StaticResource DataTemplateTimeZone}" 
                                        SelectedValuePath="ID" 
                                        ItemsSource="{Binding DataSource.TimeZoneDataSource, Source={StaticResource vmProxy}}"
                                        IsEnabled="True"/>
                </telerik:DataFormComboBoxField>

我建议使用包含observablecollection并使用http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx

的viewmodel

和StaticResource vmProxy

一样