WPF DataGrid: How do I access a ComboBox in a specific row of a DataGridTemplateColumn?

℡╲_俬逩灬. 提交于 2021-02-08 03:42:25

问题


My app correctly populates a DataGrid column with ComboBoxes, using the following XAML code:

<DataGridTemplateColumn Header="Thickness">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding SteelThickness, RelativeSource={RelativeSource AncestorType=Window}}" SelectedItem="{Binding BottomPlateThickness, UpdateSourceTrigger=PropertyChanged}" SelectionChanged="ComboBox_SelectionChanged" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

I am trying to figure out an expression such as

ComboBox cmb = dataGrid[i].Column[11].ComboBox

which will retrieve one ComboBox at a time.

TIA


回答1:


Hi after going through your question I decided to write a helper class for accesing Rows and columns by indices.I am trying to give an idea . I have not tested it well so there might be some issues.

Complete solution accessing datagrid row and column through indices

//This class will help to get Row, Column or Cell by indices. Though there might not be some proper check for null and indices Sorry for that.I will update it later.

    public static class DataGridExtension
{
    public static DataGridColumn GetColumnByIndices(this DataGrid dataGrid, int rowIndex, int columnIndex)
    {
        ValidateParameters(dataGrid, rowIndex, columnIndex);

        var row = dataGrid.GetRowByIndex(rowIndex);

        if (row != null)
            return row.GetRowColumnByIndex(columnIndex);

        return null;
    }

    public static DataGridCell GetCellByIndices(this DataGrid dataGrid, int rowIndex, int columnIndex)
    {
        ValidateParameters(dataGrid, rowIndex, columnIndex);

        var row = dataGrid.GetRowByIndex(rowIndex);

        if (row != null)
            return row.GetRowCellByColumnIndex(columnIndex);

        return null;
    }

    //TODO:Validate RowIndex
    public static DataGridRow GetRowByIndex(this DataGrid dataGrid, int rowIndex)
    {
        if (dataGrid == null)
            return null;

        return (DataGridRow)dataGrid.ItemContainerGenerator
                                                       .ContainerFromIndex(rowIndex);    
    }

    //TODO:Validate ColumnIndex
    public static DataGridColumn GetRowColumnByIndex(this DataGridRow row, int columnIndex)
    {
        if (row != null)
        {
            var cell=GetRowCellByColumnIndex(row, columnIndex);

            if(cell!=null)
                return cell.Column;
        }

        return null;
    }

    //TODO:Validate ColumnIndex
    public static DataGridCell GetRowCellByColumnIndex(this DataGridRow row, int columnIndex)
    {
        if (row != null)
        {
            DataGridCellsPresenter cellPresenter = row.GetVisualChild<DataGridCellsPresenter>();

            if (cellPresenter != null)
                return ((DataGridCell)cellPresenter.ItemContainerGenerator.ContainerFromIndex(columnIndex));
        }

        return null;
    }

    private static void ValidateParameters(DataGrid dataGrid,int rowIndex,int columnIndex)
    {
        if (dataGrid == null)
            throw new ArgumentNullException("datagrid is null");
        if (rowIndex >= dataGrid.Items.Count)
            throw new IndexOutOfRangeException("rowIndex out of Index");
        if (columnIndex >= dataGrid.Columns.Count)
            throw new IndexOutOfRangeException("columnIndex out of Index");
    }
}

****//This Class will help to find the VisualChild ****

public static class VisualHelper
{
    public static T GetVisualChild<T>(this Visual parent) where T : Visual
    {
        T child = default(T);

        for (int index = 0; index < VisualTreeHelper.GetChildrenCount(parent); index++)
        {
            Visual visualChild = (Visual)VisualTreeHelper.GetChild(parent, index);
            child = visualChild as T;

            if (child == null)
                child = GetVisualChild<T>(visualChild);//Find Recursively

            if (child != null)
                break;
        }
        return child;
    }
}

Now you can use these classes to get Columns,Cells,Rows by Index like

        private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        //Now we can get Column like this.
        var column = dataGrid.GetColumnByIndices(1, 1);

        //As SO want to find the ComboBox within that Column 
        ComboBox comboBox;
        var cell = dataGrid.GetCellByIndices(1, 1); //DataGridColumn Does'nt Inherit Visual class so using GetCellByIndices

        if(cell!=null)
            comboBox = cell.GetVisualChild<ComboBox>(); //DataGridCell Inherit Visual so we can use our VisualHelper Method
    }


来源:https://stackoverflow.com/questions/20255343/wpf-datagrid-how-do-i-access-a-combobox-in-a-specific-row-of-a-datagridtemplate

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