Is it possible to switch rows and columns in a datagridview?

痴心易碎 提交于 2019-12-28 23:08:07

问题


I have 10 records of data in a DataTable which has 3 fields "Foo", "Bar", and "Baz".

If I connect wire this into a DataGridView I see 10 rows and 3 columns, and the column headers display the names of the fields.

I'm wondering how easy it is to reverse the rows and columns so that with the same data I end up with 3 rows and 10 columns, with field names being displayed in the row headers.


I can do some things manualy, like overriding an OnPaint method and drawing the field names directly into the row header cells, but I'm looking for something more automated.

Again, there's a suggestion of swapping values manualy, but unless I make all values Strings, this isn't going to work. 3 columns in a data table - Foo, Bar, and Baz of types int, float and string just won't transpose.

Even if I managed all of these manual changes, my data grids have CheckBox columns, ComboBox columns - no such row counterpart exists - there is no CheckBox row or ComboBox row. Where I currently just need to tell the compiler to "Add a ComboBoxColumn" I'd have to re-write so that every cell was generated individually.

Ideally I'd like a TransposableDataGridView which exposed all functionality of the DataGridView, with an additional bool property "Transposed". That way I could leave all of my code exactly as it is - I wouldn't have to change anything except for the type of the grid.

If nothing like this exists, I might just have to go and write it. (Should only take me a year or so! :)


回答1:


You can create new DataTable, add appropriate number of collumns and then copy values from one table to the other, just swap rows and colums.

I don't think you can set row header in the same way you can set column header (or at least I don't know how), so you can put the field names in separate colum.

DataTable oldTable = new DataTable();

...

DataTable newTable = new DataTable();

newTable.Columns.Add("Field Name");
for (int i = 0; i < oldTable.Rows.Count; i++)
    newTable.Columns.Add();

for (int i = 0; i < oldTable.Columns.Count; i++)
{
    DataRow newRow = newTable.NewRow();

    newRow[0] = oldTable.Columns[i].Caption;
    for (int j = 0; j < oldTable.Rows.Count; j++)
        newRow[j+1] = oldTable.Rows[j][i];
    newTable.Rows.Add(newRow);
}

dataGridView.DataSource = newTable;



回答2:


I use the Developer Expres Vertical Grid.. It is like you want a rotated grid. It also allows for a different editor per row.

Link to vertical grid product page




回答3:


You can do this by programmatically adding the number of columns you need (e.g., 7 more to make 10) then programmatically swapping row, col with col, row.




回答4:


This code should do the trick http://aspalliance.com/538_CodeSnip_Pivot_Tables_with_ADONET_and_Display_in_a_DataGrid_Paged_Horizontally

The display is asp.net but you can bind the resulting datatable to datagridview and get the result you want




回答5:


Apply a LayoutTransform to the DataGrid:

<DataGrid Name = "reverseThis">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Top" Binding="{Binding Path=Top}"/>
        <DataGridTextColumn Header="Middle" Binding="{Binding Path=Middle}"/>
        <DataGridTextColumn Header="Bottom" Binding="{Binding Path=Bottom}"/>
    </DataGrid.Columns>
    <DataGrid.LayoutTransform>
        <TransformGroup>
            <RotateTransform Angle="-90"/>
            <ScaleTransform ScaleX="1" ScaleY="-1" />
        </TransformGroup>
    </DataGrid.LayoutTransform>

You also need to reverse the column headers:

<DataGrid.ColumnHeaderStyle>
    <Style TargetType="{x:Type DataGridColumnHeader}"
                                   BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
        <Setter Property="LayoutTransform">
            <Setter.Value>
                <TransformGroup>
                    <RotateTransform Angle="-90"/>
                    <ScaleTransform ScaleX="1" ScaleY="-1" />
                </TransformGroup>
            </Setter.Value>
        </Setter>
        <Setter Property="FontWeight" Value="Bold"></Setter>
    </Style>
</DataGrid.ColumnHeaderStyle>

and the cells, otherwise they come out mirrored and rotated:

    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell" >
            <Setter Property="LayoutTransform">
                <Setter.Value>
                    <TransformGroup>
                        <RotateTransform Angle="-90"/>
                        <ScaleTransform ScaleX="1" ScaleY="-1" />
                    </TransformGroup>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.CellStyle>

</DataGrid>



回答6:


In my case needed also to add a name to all columns of the new table. I wrote a function to generate a transposed table like this:

static public DataTable Transpose(DataTable inputTable, List<string> newColumnNames)
{
    DataTable outputTable = new DataTable();

    ///You should also verify if newColumnsNames.Count matches inputTable number of row

    //Creates the columns, using the provided column names.
    foreach (var newColumnName in newColumnNames)
    {
        outputTable.Columns.Add(newColumnName, typeof(string));
    }

    foreach (DataColumn inputColumn in inputTable.Columns)
    {
        //For each old column we generate a row in the new table
        DataRow newRow = outputTable.NewRow();

        //Looks in the former header row to fill in the first column
        newRow[0] = inputColumn.ColumnName.ToString();

        int counter = 1;
        foreach (DataRow row in inputTable.Rows)
        {
            newRow[counter] = row[inputColumn.ColumnName].ToString();
            counter++;
        }
        outputTable.Rows.Add(newRow);
    }

    return outputTable;

}


来源:https://stackoverflow.com/questions/853663/is-it-possible-to-switch-rows-and-columns-in-a-datagridview

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