WPF DataGrid:如何访问DataGridTemplateColumn的特定行中的ComboBox?

时间:2013-11-27 23:49:47

标签: c# wpf xaml datagrid combobox

我的应用使用以下XAML代码使用ComboBox正确填充DataGrid列:

<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>

我想找出一个表达式,例如

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

将一次检索一个ComboBox。

TIA

1 个答案:

答案 0 :(得分:2)

嗨,在完成你的问题后,我决定编写一个帮助类,用于通过索引访问行和列。我正在尝试提出一个想法。我没有测试好,所以可能会有一些问题。

  
    

完整解决方案accessing datagrid row and column through indices

  

//此类将有助于按索引获取行,列或单元格。虽然可能没有对null和索引进行一些正确的检查。对不起,我会稍后更新。

    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");
    }
}

**** //这个类将有助于找到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;
    }
}

现在您可以使用这些类按索引获取列,单元格和行

        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
    }