Вот код за рабочим примером, в котором доступные цвета отфильтровываются до цветов, указанных в списке AllColors связанного объекта.
Магия происходит в обработчиках событий CellBeginEdit
и CellEndEdit
- там мы предоставляем каждую ячейку со списком из связанной строки и затем сбрасываем ее при выходе.
Одна вещь, на которую опирается, имеет главный список, который содержит все цвета - нет никакого способа обойти это.
Также я добавил обработку для случая, когда новая строка требует значений по умолчанию. Все, что я делаю, - это установить выбранный индекс по умолчанию на один. Конечно, это не сработает в реальном мире, вам нужно что-то более умное! Событие DefaultValuedNeeded
описывает here on MSDN.
public partial class Form1 : Form
{
private BindingSource cars;
private BindingSource masterColors;
public Form1()
{
InitializeComponent();
masterColors = new BindingSource();
masterColors.Add(new CarColor{Name = "Blue", Index = 1});
masterColors.Add(new CarColor{Name = "Red", Index = 2});
masterColors.Add(new CarColor { Name = "Green", Index = 3 });
masterColors.Add(new CarColor { Name = "White", Index = 4 });
BindingList<CarColor> fordColors = new BindingList<CarColor>();
fordColors.Add(new CarColor{Name = "Blue", Index = 1});
fordColors.Add(new CarColor{Name = "Red", Index = 2});
BindingList<CarColor> toyotaColors = new BindingList<CarColor>();
toyotaColors.Add(new CarColor { Name = "Green", Index = 3 });
toyotaColors.Add(new CarColor { Name = "White", Index = 4 });
cars = new BindingSource();
cars.Add(new Car { Make = "Ford", SelectedColorIndex = 1, AllColors = fordColors });
cars.Add(new Car { Make = "Toyota", SelectedColorIndex = 3, AllColors = toyotaColors });
dataGridView1.DataSource = cars;
dataGridView1.Columns["SelectedColorIndex"].Visible = false;
//dataGridView1.Columns["AllColors"].Visible = false;
DataGridViewComboBoxColumn col = new DataGridViewComboBoxColumn();
col.Name = "AvailableColors";
col.DataSource = masterColors;
col.DisplayMember = "Name";
col.DataPropertyName = "SelectedColorIndex";
col.ValueMember = "Index";
dataGridView1.Columns.Add(col);
dataGridView1.CellBeginEdit += new DataGridViewCellCancelEventHandler(dataGridView1_CellBeginEdit);
dataGridView1.CellEndEdit += new DataGridViewCellEventHandler(dataGridView1_CellEndEdit);
dataGridView1.DefaultValuesNeeded += new DataGridViewRowEventHandler(dataGridView1_DefaultValuesNeeded);
}
void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
if (e.ColumnIndex == dataGridView1.Columns["AvailableColors"].Index)
{
if (e.RowIndex != dataGridView1.NewRowIndex)
{
// Set the combobox cell datasource to the filtered BindingSource
DataGridViewComboBoxCell dgcb = (DataGridViewComboBoxCell)dataGridView1
[e.ColumnIndex, e.RowIndex];
Car rowCar = dataGridView1.Rows[e.RowIndex].DataBoundItem as Car;
dgcb.DataSource = rowCar.AllColors;
}
}
}
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == dataGridView1.Columns["AvailableColors"].Index)
{
// Reset combobox cell to the unfiltered BindingSource
DataGridViewComboBoxCell dgcb = (DataGridViewComboBoxCell)dataGridView1
[e.ColumnIndex, e.RowIndex];
dgcb.DataSource = masterColors; //unfiltered
}
}
void dataGridView1_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
{
e.Row.Cells["SelectedColorIndex"].Value = 1;
}
}
public class Car
{
public String Make { get; set; }
public BindingList<CarColor> AllColors { get; set; }
public int SelectedColorIndex { get; set; }
}
public class CarColor
{
public String Name { get; set; }
public int Index { get; set; }
}
я впервые узнал, как это сделать из DataGridView FAQ, большой ресурс, написанный Марком Rideout, руководителем программы в то время для DataGridView
в Microsoft. Пример в фильтрах часто задаваемых вопросов, основанный на другом поле со списком, и использует DataTables, но принцип тот же.
Итак, вы хотите, чтобы выпадающие списки для каждого автомобиля предлагали разные цвета? Являются ли цвета для каждого автомобиля подмножеством всех доступных цветов? –
Да. У каждого автомобиля есть свои доступные цвета, и они не являются подмножеством множества «больших доступных цветов». (это просто пример в моем случае, каждый объект имеет собственный набор доступных свойств, которые снова являются объектами. Я сделал этот пример, чтобы сделать вещи более простыми). – Ben
У меня будет пример, который, надеюсь, вскоре ответит на вопрос. Примерно через полпути через прототипирование. –