Search code examples
c#wpfdatagriddatagridcomboboxcolumndatagridtextcolumn

Setting value of datagridtextcolumn cell WPF application


Good day

I must be missing something really simple here; I have a datagrid with two combobox columns and a datagridtextcolumn. Once the user has selected a value for both of these comboboxes (a value ranging from 1 to 5), a calculation is done with these 2 values (on a combobox selection changed event). I need to write the result of the calculation in to a cell (the datagridtextcolumn) and change the background of that cell to a specific colour based on the value. I have managed to find the values in the comboboxes and the index of the current row, but accessing the relevant cell to write the result to is getting the better of me...

Here is the coding for the event handler that calls the calculation thus far:

private void cmbConseq_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var cellInfos = dgDeviation.SelectedCells;
    if (cellInfos == null)
    {
        return;
    }
    var content = cellInfos[0].Column.GetCellContent(cellInfos[0].Item);
    DataRowView row = (DataRowView)content.DataContext;//get the datacontext from FrameworkElement and typecast to DataRowView
    object[] obj = row.Row.ItemArray;//ItemArray returns an object array with single element
    int likely = Convert.ToInt16(obj[0]);
    int cons = Convert.ToInt16(obj[1]);
    int riskValue = new Calculations().riskRankingCalc(likely, cons);

    int rowIndex = dgDeviation.Items.IndexOf(dgDeviation.CurrentItem);

How do I write the 'riskValue' variable to the relevant cell in the currently selected row in the eventhandler?


Solution

  • After a bit of experimentation and help from other SO questions, the solution that worked for me was to implement the following two helper methods:

        public static T GetVisualChild<T>(Visual parent) where T : Visual
        {
            T child = default(T);
            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < numVisuals; i++)
            {
                Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                child = v as T;
                if (child == null)
                {
                    child = GetVisualChild<T>(v);
                }
                if (child != null)
                {
                    break;
                }
            }
            return child;
        }
    
        public static DataGridCell GetCell(DataGrid grid, int column)
        {
            DataGridRow row = grid.ItemContainerGenerator.ContainerFromIndex(grid.SelectedIndex) as DataGridRow;
    
            if (row != null)
            {
                DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
    
                if (presenter == null)
                {
                    grid.ScrollIntoView(row, grid.Columns[column]);
                    presenter = GetVisualChild<DataGridCellsPresenter>(row);
                }
    
                DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
                return cell;
            }
            return null;
        }
    

    And then to make the change in the cell is as easy as calling: GetCell(myDatagrid, columnIndex).Content = "New Value";