This is a migrated thread and some comments may be shown as answers.

Advanced GridViewColumnGroup?

3 Answers 167 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Francois
Top achievements
Rank 1
Francois asked on 15 Apr 2013, 12:48 PM
Hi, I have a very special requirement to address.

I'm looking to manipulate the RadGridView to some sort of PivotTable, but I need to edit the objects that the grid will be bound to (would be great to run in bound mode), and by edit I mean drag and drop the 'Projects' to different weeks of months (but that's another problem).

My current problem is about altering the UI of the grid, so that it can be more intuitive for the user and also easier to maintain.

Please see the screenshots in attachment to understand my goal.

Thanks,

--
Francois




using System;
using System.Collections.Generic;
using System.Data;
using System.Windows.Forms;
using Telerik.WinControls.UI;
 
namespace WindowsFormsApplication3
{
    public  class Form1 : Form
    {
        private const string WeekDisplayedName = "Week";
 
        private RadGridView Grid { get { return this.radGridView1; } }
 
        private struct ColsGrid
        {
            public const string Level1 = "Level 1 Criteria";
            public const string Level2 = "Level 2 Criteria";
            public const string FakeLevel = "Fake row";
        }
 
        public Form1()
        {
            InitializeComponent();
 
            InitializeGrid();
        }
 
        /// <summary>
        ///
        /// </summary>
        private void InitializeGrid()
        {
            this.Grid.ShowFilteringRow = false;
            this.Grid.ShowGroupPanel = false;
            this.Grid.SelectionMode = GridViewSelectionMode.CellSelect;
            this.Grid.AllowAddNewRow = this.Grid.AllowDeleteRow = false;
 
            // Data
            var table = new DataTable();
 
            table.Columns.Add(ColsGrid.Level1, typeof(string));
            table.Columns.Add(ColsGrid.Level2, typeof(string));
            table.Columns.Add(ColsGrid.FakeLevel, typeof(string));
 
            var lst = new List<Tuple<string, string>>();
 
            lst.Add(new Tuple<string, string>("Level 1-A", "Level 2-A"));
            lst.Add(new Tuple<string, string>("Level 1-A", "Level 2-B"));
            lst.Add(new Tuple<string, string>("Level 1-A", "Level 2-C"));
            lst.Add(new Tuple<string, string>("Level 1-B", "Level 2-A"));
            lst.Add(new Tuple<string, string>("Level 1-B", "Level 2-B"));
            lst.Add(new Tuple<string, string>("Level 1-B", "Level 2-C"));
 
            this.Grid.AutoExpandGroups = true;
            this.Grid.DataSource = table;
 
            //this.Grid.GroupDescriptors.Add(new GroupDescriptor("Project"));
            this.Grid.Columns.Add(new GridViewTextBoxColumn(ColsGrid.Level1));
            this.Grid.Columns.Add(new GridViewTextBoxColumn(ColsGrid.Level2));
            this.Grid.Columns.Add(new GridViewTextBoxColumn(ColsGrid.FakeLevel));
 
            this.Grid.Columns[ColsGrid.Level1].Width = 100;
            this.Grid.Columns[ColsGrid.Level2].Width = 100;
            this.Grid.Columns[ColsGrid.FakeLevel].IsVisible = false;
 
            // Create fake lines for each level1/level2
            int nbLines = 3;
            foreach (var item in lst)
            {
                for (var i = 0; i < nbLines; i++)
                {
                    table.Rows.Add(item.Item1, item.Item2, i);
                }
            }
 
            // Add timeline columns
            string[] months = new string[] { "January", "Febuary", "March", };
 
            for (int i = 0; i < months.Length; i++)
            {
                for (int j = 1; j <= 4; j++)
                {
                    GridViewTextBoxColumn column = new GridViewTextBoxColumn(months[i] + WeekDisplayedName + j);
                    column.HeaderText = WeekDisplayedName + " " + j.ToString();
                    column.Width = 75;
 
                    this.Grid.Columns.Add(column);
                }
            }
 
            // Group the 3 first columns
            var def = new ColumnGroupsViewDefinition();
            var colGroup = new GridViewColumnGroup("Row header group");
            colGroup.ShowHeader = false;
            colGroup.Rows.Add(new GridViewColumnGroupRow());
            colGroup.Rows[0].Columns.Add(this.Grid.Columns[ColsGrid.Level1]);
            colGroup.Rows[0].Columns.Add(this.Grid.Columns[ColsGrid.Level2]);
            colGroup.Rows[0].Columns.Add(this.Grid.Columns[ColsGrid.FakeLevel]);
            def.ColumnGroups.Add(colGroup);
 
            // Create a group for each month, each containing 4 weeks
            for (int i = 0; i < months.Length; i++)
            {
                def.ColumnGroups.Add(new GridViewColumnGroup(months[i]));
                def.ColumnGroups[1 + i].Rows.Add(new GridViewColumnGroupRow());
 
                for (int j = 1; j <= 4; j++)
                {
                    def.ColumnGroups[1 + i].Rows[0].Columns.Add(this.Grid.Columns[months[i] + WeekDisplayedName + j]);
                }
            }
 
            this.Grid.ViewDefinition = def;
 
            // Create fake data
            this.Grid.Rows[0].Cells[months[0] + WeekDisplayedName + "1"].Value = "Project 1";
            this.Grid.Rows[1].Cells[months[0] + WeekDisplayedName + "1"].Value = "Project 2";
            this.Grid.Rows[9].Cells[months[0] + WeekDisplayedName + "3"].Value = "Project 3";
            this.Grid.Rows[4].Cells[months[1] + WeekDisplayedName + "2"].Value = "Project 4";
            this.Grid.Rows[7].Cells[months[1] + WeekDisplayedName + "3"].Value = "Project 5";
        }
 
        #region Designer stuff
        /// <summary>
        /// Variable nécessaire au concepteur.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
 
        /// <summary>
        /// Nettoyage des ressources utilisées.
        /// </summary>
        /// <param name="disposing">true si les ressources managées doivent être supprimées ; sinon, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
 
        #region Code généré par le Concepteur Windows Form
 
        /// <summary>
        /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas
        /// le contenu de cette méthode avec l'éditeur de code.
        /// </summary>
        private void InitializeComponent()
        {
            this.radGridView1 = new Telerik.WinControls.UI.RadGridView();
            ((System.ComponentModel.ISupportInitialize)(this.radGridView1)).BeginInit();
            this.SuspendLayout();
            //
            // radGridView1
            //
            this.radGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.radGridView1.Location = new System.Drawing.Point(0, 0);
            this.radGridView1.Name = "radGridView1";
            this.radGridView1.Size = new System.Drawing.Size(1137, 629);
            this.radGridView1.TabIndex = 0;
            this.radGridView1.Text = "radGridView1";
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1137, 629);
            this.Controls.Add(this.radGridView1);
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this.radGridView1)).EndInit();
            this.ResumeLayout(false);
 
        }
 
        #endregion
 
        private Telerik.WinControls.UI.RadGridView radGridView1;
        #endregion
    }
}

3 Answers, 1 is accepted

Sort by
0
Peter
Telerik team
answered on 18 Apr 2013, 10:56 AM
Hi Francois,

Thank you for writing.

You should use our RadPivotGrid which provides functionality very similar to the functionality that you request.

Alternatively, you can try to customize RadGridView using its CellFormatting event. You can access the cell visual element's Text property and BorderStyle property only in the CellFormatting event because RadGridView is virtualized control and a few visual items (for example 25) represents many logical items (the whole table) e.g. the visual items are reused. For example you can remove the text from all cells in column 1 except the cell in row 4 in this way: 
public Form1()
{
    InitializeComponent();
    InitializeGrid();
    this.Grid.CellFormatting += new CellFormattingEventHandler(Grid_CellFormatting);
}
 
void Grid_CellFormatting(object sender, CellFormattingEventArgs e)
{
    if (e.CellElement.ColumnIndex == 0)
    {
        GridViewCellInfo cellInfo = e.Row.Cells[e.ColumnIndex];
        cellInfo.Style.CustomizeBorder = true;
        e.CellElement.BorderBoxStyle = Telerik.WinControls.BorderBoxStyle.FourBorders;
        e.CellElement.BorderBottomWidth = 0;
        e.CellElement.BorderTopWidth = 0;
         
        if (e.CellElement.RowIndex==4)
        {
            e.CellElement.DrawText = true;
        }
        else
        {
            e.CellElement.DrawText = false;
        }
         
    }
    else
    {
        e.CellElement.ResetValue(LightVisualElement.BorderBoxStyleProperty, Telerik.WinControls.ValueResetFlags.Local);
        e.CellElement.DrawText = true;
    }
}

Please, note that these cells will be editable and its text will appear in edit mode. So, I can suggest using RadPivotGrid instead of customizing RadGridView control.

I hope this helps.

Regards,
Peter
the Telerik team
WinForms Q1 2013 boasts PivotGrid, PDF Viewer, Chart enhancements and more. Check out all of the latest highlights.
0
Francois
Top achievements
Rank 1
answered on 18 Apr 2013, 12:27 PM
Hi, thank you for the answer.

I tried to use the RadPivotGrid, but I need to provide an aggregate operation/value (sum, average,  max, count...) that can be displayed. I didn't find a way to make the control simply group by distinct value.

Could you provide or point me to an example to do this?

Thanks,

--
Francois
0
Peter
Telerik team
answered on 19 Apr 2013, 01:15 PM
Hello Francois,

Thank you for writing back.

RadPivotGrid provides the following functions: Sum, Count, Average, Max, Min, Product, StdDev, StdDevP, Var and VarP. For example:
this.radPivotGrid1.AggregateDescriptions.Add(new PropertyAggregateDescription() { PropertyName = "Quantity", AggregateFunction = AggregateFunctions.Sum });
 this.radPivotGrid1.AggregateDescriptions.Add(new PropertyAggregateDescription() { PropertyName = "Discount", AggregateFunction = AggregateFunctions.Average });

These lines of code will add two aggregate descriptors one with Sum and one with Average calculations.
There is a sample in our Demo application. You can take a look at RadPivotGrid in action, at the following section: RadPivotGrid >> First Look. The source code for the demo is also available there.

Also, I would like to recommend you to read this help article.

If this is not suitable for you, please try to customize the cells borders using the CellFormatting event as I mentioned in my previous ticket.

I hope this helps. Let me know if you have any additional questions.

Kind regards,
Peter
the Telerik team
WinForms Q1 2013 boasts PivotGrid, PDF Viewer, Chart enhancements and more. Check out all of the latest highlights.
Tags
GridView
Asked by
Francois
Top achievements
Rank 1
Answers by
Peter
Telerik team
Francois
Top achievements
Rank 1
Share this question
or