DataGridView, BindingList<T>, DataGridViewComboBoxColumn
-
21-08-2019 - |
Вопрос
Итак, у меня есть DataGridView, использующий в качестве источника данных BindingList.
DataGridView.DataSource = new BindingList<Car>{...}
Где
public class Car
{
public ColorName Color { get; set;}
}
с
public class ColorName
{
public int Id {get; set;}
public string Name{get; set;}
}
и я использую столбец Combobox:
DataGridViewComboBoxColumn colorNameDataGridViewTextBoxColumn;
colorNameDataGridViewTextBoxColumn.DataPropertyName = "Color";
colorNameDataGridViewTextBoxColumn.HeaderText = "Color";
colorNameDataGridViewTextBoxColumn.Name = "Color";
colorNameDataGridViewTextBoxColumn.DisplayMember = "Name";
colorNameDataGridViewTextBoxColumn.ValueMember = "Id";
colorNameDataGridViewTextBoxColumn.DataSource = new ColorName[] {...};
Как мне заставить это работать?!Теперь я получаю исключение, потому что думаю, что оно пытается привести идентификатор к ColorName.
Я попробовал использовать пустой ValueMember или добавить оператор прямого приведения к классу ColorName, но не смог заставить его работать.
Конечно, я могу использовать int в классе Car для представления цвета, но это не так удобно.
Как вы, наверное, догадались, эти классы на самом деле являются Castle Project ActiveRecord.
Любые идеи приветствуются!
Решение
Вы пробовали ValueMember = "" или ValueMember = "."?
Действительно хакерски, но вы можете добавить свойство ColorName
это само собой?(возможно, через частичный класс)
public ColorName Self {get {return this;}}
затем установите `ValueMember = "Self";'
Помимо этого, вам, вероятно, понадобится TypeConverter
Другим вариантом может быть переопределение ToString()
на ColorName
вернуться Name
, и не иметь члена значения/отображения?
(обновлять:нет, это не так)
Проверили и ToString()
кажется работает:
public override string ToString() { return Name; }
и просто не устанавливайте DisplayMember
или а ValueMember
.
Ну, что вы знаете, трюк с «Я» тоже работает…
using System;
using System.ComponentModel;
using System.Windows.Forms;
class ColorName
{
public ColorName(int id, string name) {
this.Id = id;
this.Name = name;
}
public int Id { get; private set; }
public string Name { get; private set; }
// maybe declare this one in a partial class...
public ColorName Self { get { return this; } }
}
class Car
{
public ColorName Color { get; set; }
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
using(Form form = new Form())
using (DataGridView grid = new DataGridView())
{
grid.Dock = DockStyle.Fill;
grid.AutoGenerateColumns = false;
ColorName[] colors = new[] {
new ColorName(1,"Red"),
new ColorName(2,"Blue"),
new ColorName(3,"Green")
};
var col = new DataGridViewComboBoxColumn
{
DataPropertyName = "Color",
HeaderText = "Color",
Name = "Color",
DisplayMember = "Name",
ValueMember = "Self",
DataSource = colors
};
grid.Columns.Add(col);
grid.DataSource = new BindingList<Car> {
new Car { Color = colors[0]}
};
form.Controls.Add(grid);
Application.Run(form);
}
}
}