0
votes

My code:

private void InitGrid(DataTable dataTable, ref DataGridView grid, bool resetColumns)
{
    if (grid.Columns.Count > 0)
    {
        if (resetColumns)
        {
            grid.Columns.Clear();
            grid.DataSource = null;
        }
        else
        {
            return;
        }
    }
    DataGridViewColumn column;
    grid.AutoGenerateColumns = false;
    // apply entire data from table to grid.
    grid.DataSource = dataTable;

    // set column properties according to their type (combo, text, etc.)
    foreach (DataColumn col in dataTable.Columns)
    {
        if (m_ColumnTypes[col.ColumnName].Equals("COMBO"))
        {
            // get query number to load specific column's data
            string adminQuery = Server.LoadData("633", new List<string>() { col.ColumnName, m_TableFullName }).Rows[0][0].ToString();
            column = new DataGridViewComboBoxColumn();
            string queryParam = Controller.MainController.User;
            switch (col.ColumnName.ToUpper())
            {
                case "FIELD1NAME":
                    (column as DataGridViewComboBoxColumn).DisplayMember = col.ColumnName;
                    (column as DataGridViewComboBoxColumn).ValueMember = "field1id";
                    break;
                case "FIELD2NAME":
                    (column as DataGridViewComboBoxColumn).DisplayMember = col.ColumnName;
                    (column as DataGridViewComboBoxColumn).ValueMember = "field2id";
                    queryParam = string.Concat("select column_value from table(fn_mgr_workspaces('", Controller.MainController.User, "'))");
                    break;
                case "PRIORITY":
                    (column as DataGridViewComboBoxColumn).DisplayMember = col.ColumnName;
                    (column as DataGridViewComboBoxColumn).ValueMember = col.ColumnName;
                    queryParam = "10";    
                    break;
            }
            (column as DataGridViewComboBoxColumn).DataSource = Server.LoadData(adminQuery, new List<string>() { queryParam });
        }
        else
        {
            column = new DataGridViewTextBoxColumn() { AutoSizeMode = m_ColumnTypes[col.ColumnName].Equals("TAGS") ? DataGridViewAutoSizeColumnMode.Fill : DataGridViewAutoSizeColumnMode.AllCells, ReadOnly = true };
        }

        column.Name = col.ColumnName.ToUpper();
        column.HeaderText = m_ColumnNameTranslations[col.ColumnName.ToUpper()];
        column.DataPropertyName = column is DataGridViewComboBoxColumn ? (column as DataGridViewComboBoxColumn).ValueMember : col.ColumnName;

        grid.Columns.Add(column);
    }

    // after setting columns. going over every row and trying to filter out the datasource of field2. this is where my problem is
    foreach (DataGridViewRow dgvr in grid.Rows)
    {
        if (!dgvr.IsNewRow)
        {
            string wsId = dgvr.Cells["filed1id"].Value.ToString();
            DataTable filteredData = ((dgvr.Cells["field2name"] as DataGridViewComboBoxCell).DataSource as DataTable).Select("thefieldname = " + wsId).CopyToDataTable();
            DataView dv = filteredData.DefaultView;
            dv.Sort = "field2name";
            (dgvr.Cells["field2name"] as DataGridViewComboBoxCell).DataSource = null;
            (dgvr.Cells["field2name"] as DataGridViewComboBoxCell).DisplayMember = "field2name";
            (dgvr.Cells["field2name"] as DataGridViewComboBoxCell).ValueMember = "field2id";
            (dgvr.Cells["field2name"] as DataGridViewComboBoxCell).DataSource = dv.ToTable();
        }
    }
}

(field names and some object names were scrambled for security purposes)

My problem:

The DataSource of field2 which is a ComboboxColumn does not change. It always shows me the entire data and not the filtered data that I try to set for it. Even though I nullify it and re-set it to the filtered data, it doesn't work.

What I'm trying to achieve is that the DataSource in field2 column should be dependant on the data of field1 for each row of the grid.

I tried setting the datasource for the other columns and not setting it for field2 and then after that going over every row and setting the filtered datasource on field2 but it comes up completely empty as if the datasource set for every row hasn't worked at all.

I'm doing something wrong. How the hell do I do this?

1

1 Answers

1
votes

The EditControlShowing event on the DataGridView will allow you to accomplish this.

Add an event handler to this method.

private void grid_EditingControlShowing(object sender, 
    DataGridViewEditingControlShowingEventArgs e)
{
    if ( grid.CurrentCell.ColumnIndex == dgvr.Columns["field2name"].Index )
    {

         // Get Combobox
         ComboBox combo = e.Control as ComboBox;

         // Get Other Column's Value
         string wsId = grid.Rows[grid.CurrentCell.RowIndex].Cells["filed1id"].Value.ToString();

         // Get Filtered Data Based Off Of Other Column's Value
         DataTable filteredData = (combo.DataSource as DataTable).Select("thefieldname = " + wsId).CopyToDataTable();
         DataView dv = filteredData.DefaultView;
         dv.Sort = "field2name";


         // Rebind
         combo.DataSource = null;
         combo.DisplayMember = "field2name";
         combo.ValueMember = "field2id";
         combo.DataSource = dv.ToTable();
    }
}