Skip to main content Skip to footer

Transposed FlexGrid (WPF & Silverlight)

There are times when user wants to see data as transposed i.e vertical rows and horizontal columns in grid. The simplest way to do this is use the DataTable object as the ItemsSource and transpose the data itself there. The objective becomes a bit complex to achieve when using native collection of objects as the ItemsSource. Thanks to flexibility offered by C1FlexGrid which can be used to accomplish our objective in these scenarios. Everything in this case has to be done manually, i.e create rows/columns manually, fill row headers with required column text, bound transposed cells with data etc. Here is a simple class which we will be using in this case:-


public class ClubTransfers  
{  
    public string Player { get; set; }  
    public string Country { get; set; }  
    public string From { get; set; }  
    public string To { get; set; }  
    public string Price { get; set; }  
    public string Year { get; set; }  
}  

Now,Lets inherit C1FlexGrid and create a custom flexgrid. All columns/rows would be added manually in the inherited class:-


public class CustomFlexGrid:C1FlexGrid  
{  
    protected override void OnLoadedRows(EventArgs e)  
    {  
        base.OnLoadedRows(e);  
        var vm = new TransferViewModel();  
        this.AutoGenerateColumns = false;  
        this.HeadersVisibility = HeadersVisibility.Row;  
        this.CellFactory = new TransposeCellFactory();  

        // add columns  
        for (int i = 0; i < vm.Count; i++)  
        {  
            this.Columns.Add(new Column() { Tag = vm.Transfers[i], TextWrapping = true });  
        }  

        //add rows  
        this.Rows.Clear();  
        var ct = new ClubTransfers();  
        foreach (PropertyInfo pi in ct.GetType().GetProperties())  
        {  
            this.Rows.Add(new Row() { Tag = pi.Name });  
        }  

        //autosize rows/columns  
        this.Loaded += (s1, e1) =>  
        {  
            this.AutoSizeRows(0, this.Rows.Count - 1, 0);  
            this.AutoSizeFixedColumn(0, 0);  
            this.AutoSizeFixedRow(0, 0);  
            this.AutoSizeColumns(0, this.Columns.Count - 1, 0);  
        };  
    }  
}  

The next code snippet creates the CellFactory for binding the cells and filling row headers:-


public class TransposeCellFactory : CellFactory  
{  
    public override void CreateRowHeaderContent(C1FlexGrid grid, Border bdr, CellRange range)  
    {  
        // Assign text to row headers  
        var row = grid.Rows[range.Row];  
        var c = grid.Columns[range.Column];  
        var textblock = new TextBlock();  
        if (row.Tag != null)  
        {  
            textblock.Text = row.Tag.ToString();  
        }  
        bdr.Child = textblock;  
    }  

    public override FrameworkElement CreateCellEditor(C1FlexGrid grid, CellType cellType, CellRange range)  
    {  
        var row = grid.Rows[range.Row];  
        var c = grid.Columns[range.Column];  
        var textbox = new TextBox();  
        if (row.Tag != null)  
        {  
            textbox.DataContext = c.Tag;  
            var binding = new Binding(row.Tag.ToString()) { Mode = BindingMode.TwoWay };  
            textbox.SetBinding(TextBox.TextProperty, binding);  
        }  
        return textbox;  
    }  

    public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange range)  
    {  
        var row = grid.Rows[range.Row];  
        var c = grid.Columns[range.Column];  
        var textblock = new TextBlock();  
        if (c.Tag != null)  
        {  
            bdr.DataContext = c.Tag ;  
            var binding = new Binding(row.Tag.ToString()) { Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged };  
            textblock.SetBinding(TextBlock.TextProperty, binding);  
            bdr.Child = textblock;  
        }  
    }  
}  

The xaml code for our custom flexgrid is next:-


<local:CustomFlexGrid Grid.Row="1" MinRowHeight="25"  x:Name="flex"  ItemsSource="{Binding Transfers}" AutoGenerateColumns="False"   />  

This will be the output on running the sample:- Download Sample

MESCIUS inc.

comments powered by Disqus