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

6

9

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! :)

Mcspadden answered 12/5, 2009 at 16:27 Comment(1)
Switch rows and columns in DataGridViewImmobilize
P
6

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;
Psychodynamics answered 12/5, 2009 at 19:13 Comment(3)
Thanks for the answer - what happens if I have an bool DataColumn and a string DataColumn - what type do I make the columns of the transposed grid?Mcspadden
If you don't set the type, it defaults to string, so if you just want to show the data to the user that's fine for you, because values of other types will be automatically converted. The other possibility is to set the type to object. Variable of this type can contain anything.Psychodynamics
The header text is the least of all problems -- "The header cell of a row is typically used to display a row label." newRow.HeaderCell.Value = "Row Header Text";Throckmorton
L
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

Lamori answered 5/8, 2009 at 13:8 Comment(0)
N
1

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.

Neighbor answered 12/5, 2009 at 17:9 Comment(1)
Are you suggesting add columns to the DataTable or to the DataGridView?Mcspadden
V
1

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>
Villeinage answered 11/7, 2019 at 14:35 Comment(2)
I realise the original question was about DataGridView but my answer is for DataGrid. This post is the first Google hit for "datagrid swap rows and columns" so I'll leave it.Villeinage
It would be better to ask a separate parallel question for WPF DataGrid if one doesn't already exist, and then edit this question with a simple note "For WPF, see (link to WPF version of question)" The other question should include a reverse link, "For WinForms DataGridView" Adding wrong answers just because the question has Google juice is really frowned upon.Throckmorton
C
0

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;

}
Coon answered 25/9, 2015 at 12:18 Comment(0)
H
0

Transposing is not a feature of DataGridView. Even if you create a new DataTable, you won't be changing the datatype of each cell.

You can use a different datagrid control, such as ComponentOne FlexGrid from Mescius. The code to transpose FlexGrid is straightforward:

c1FlexGrid1.Transposed = true;
c1FlexGrid1.AutoSizeRows();
c1FlexGrid1.AutoSizeCols();

Autosizing the rows and columns is not necessary but it's a nice touch.

Holden answered 7/6, 2024 at 21:43 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.