Dynamically setting DataGridViewComboBoxCell's DataSource to filtered DataView based off of other cell selection

*爱你&永不变心* 提交于 2019-12-05 22:06:44

Your code can be simplified to this with no exception throwing:

    if (e.ColumnIndex == 0 && e.RowIndex > -1)
    {
        var dgv = sender as DataGridView;

        var cell = dgv[e.ColumnIndex + 1, e.RowIndex] as DataGridViewComboBoxCell;
        if (cell == null)
            return;

        cell.DataSource = ((DataTable)((DataGridViewComboBoxColumn)dgv.Columns[e.ColumnIndex + 1]).DataSource).Select("BoundID = " + dgv.CurrentCell.Value);                
    }

Updated

When you change an already set item in first combo box since the filtered dataview in the second combobox have different ID1, an exception is thrown with "DataGridViewComboBoxCell value is not valid.". In order to catch this exception register datagridview DataError event with no code in the registered method. Then when you change the already set combbox, the corresponding combobox will be filled with correct items.

This is the quick stop shop for the solution that worked for me, but I still wanted to give Mohsen the credit. Duplicated this in the original question.

I have redefined the CellValueChanged event handler per Mohsen's suggestions:

private void dg_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == 0 && e.RowIndex > -1)
    {
        var dgv = sender as DataGridView;

        var cell = dgv[e.ColumnIndex + 1, e.RowIndex] as DataGridViewComboBoxCell;
        if (cell == null)
            return;

        DataView dv = new DataView( ((DataTable)((DataGridViewComboBoxColumn)dgv.Columns[e.ColumnIndex + 1]).DataSource), "ID1 = " + dgv.CurrentCell.Value, "DisplayOrder", DataViewRowState.CurrentRows);
        if(dv.Count == 0)
            return;

        cell.DisplayMember = "Display2"; // Have to redefine the Display/Value members
        cell.ValueMember = "ID2";
        cell.DataSource = dv;
    }
}

And I have added in an event handler for the DataError like he suggested:

void dg_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
    if(e.ColumnIndex != 1)
    {
        //Alert the user for any other DataError's outside of the column I care about
        MessageBox.Show("The following exception was encountered: " + e.Exception);
    }
}

This seems to work perfectly.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!