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

GridView Virtualization CustomColumn

9 Answers 115 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Inelcis
Top achievements
Rank 1
Inelcis asked on 04 Jul 2017, 07:04 PM

Good evening,

 

I was trying to implement a generic column where depending the type of object being bind to it, different editors would be used.

At this moment i've settled for boolean, text and list and everyting is working well except the display of the checkbox.

The following happens: GridVirtualization

As you can see in the picture above, the top of the grid shows up fine, but on the bottom the checkboxes show up as text, as i use the scroll bar the lines eventually refresh to display the checkboxes(wich is why i assume this is something regarding the UI Virtualization).

I have tried invallidating rows, using dgvCustomer.TableElement.Update(Telerik.WinControls.UI.GridUINotifyAction.Reset) and a couple of alternatives that i have forgotten meantime.

The setup uses 3 custom cells, and the following custom column.

01.using System;
02.using System.Collections.Generic;
03.using Telerik.WinControls.UI;
04. 
05.namespace Inl.TelerikExtensions40.WinForms
06.{
07.    public class GenericDataColumn : GridViewDataColumn
08.    {
09. 
10.        public GenericDataColumn() : base()
11.        {
12.        }
13. 
14.        public GenericDataColumn(string fieldName) : base(fieldName)
15.        {
16.        }
17. 
18.        public GenericDataColumn(string uniqueName, string fieldName) : base(uniqueName, fieldName)
19.        {
20.        }
21. 
22.        public override Type GetCellType(GridViewRowInfo row)
23.        {
24.            if (row is GridViewDataRowInfo)
25.            {
26.                if (row.Tag != null)
27.                {
28.                    var types = (Dictionary<int, Type>)row.Tag;
29.                    if (types.ContainsKey(base.Index))
30.                    {
31.                        return types[base.Index];
32.                    }
33.                }
34. 
35.                return typeof(CustomTextBoxCell);
36.            }
37.            return base.GetCellType(row);
38.        }
39. 
40.        public override Type GetDefaultEditorType()
41.        {
42.            var cellType = GetCellType(base.OwnerTemplate.DataView.CurrentItem);
43. 
44.            if (cellType == typeof(CustomTextBoxCell)) {
45.                return typeof(RadTextBoxEditor);
46.            }
47.            if (cellType == typeof(CustomCheckBoxCell))
48.            {
49.                return typeof(CustomCheckBoxEditor);
50.            }
51.            if (cellType == typeof(CustomComboBoxCell))
52.            {
53.                return typeof(RadDropDownListEditor);
54.            }
55. 
56.            return base.GetDefaultEditorType();
57.        }
58. 
59.        public void SetType(Enumeration.DataTypesEnum tipo, GridViewRowInfo row)
60.        {
61.            Dictionary<int, Type> types = default(Dictionary<int, Type>);
62. 
63.            if (row.Tag != null)
64.            {
65.                types = (Dictionary<int, Type>)row.Tag;
66.            }
67.            else
68.            {
69.                types = new Dictionary<int, Type>();
70.            }
71. 
72.            if (types.ContainsKey(base.Index) == false)
73.            {
74.                switch (tipo)
75.                {
76.                    case Enumeration.DataTypesEnum.Texto:
77.                        types.Add(base.Index, typeof(CustomTextBoxCell));
78.                        break;
79.                    case Enumeration.DataTypesEnum.Booleano:
80.                        types.Add(base.Index, typeof(CustomCheckBoxCell));
81.                        break;
82.                    case Enumeration.DataTypesEnum.Lista:
83.                        types.Add(base.Index, typeof(CustomComboBoxCell));
84.                        break;
85.                }
86.            }
87. 
88.            row.Tag = types;
89.            //row.InvalidateRow();
90.        }
91.    }
92.}

 

I'll be willing to supply any other code necessary.

Thank you in advance.

9 Answers, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 05 Jul 2017, 10:41 AM
Hello Inelcis, 

Thank you for writing.  

Thanks to the UI virtualization mechanism in RadGridView only the currently visible cells are created and they are further reused when needed. A cell element is reused in other rows or columns if it is compatible with them. You can create a custom column and define that the custom cell is compatible with that column only. This will prevent the cell from being unintentionally reused by other columns. For this purpose, it is necessary to override the IsCompatible method of the custom cell and return true only for columns and rows that are eligible. You can find a sample approach in the following help article: http://docs.telerik.com/devtools/winforms/gridview/cells/creating-custom-cells

I hope this information helps. Should you have further questions I would be glad to help.

Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Inelcis
Top achievements
Rank 1
answered on 05 Jul 2017, 11:02 AM

Hello Dess,

Thank you for the answer.

I am aware of that behaviour wich is why i assumed it could be related to the UI Virtualization. This is just a wild guess but the best i have so far, since the form opens at a specific size before maximizing itself those checkboxes show up correctly, and after tthat the window and as such the grid expand in size but the grid cells that are visible to the user somehow are not refreshed(untill i edit the value of a cell, or scroll the vertical bar). It would be really important for me to solve this visual effect, i'll add the code for custumn cells, editor and form. Thanks again.

01.using System;
02.using Telerik.WinControls.UI;
03.
04.namespace Inl.TelerikExtensions40.WinForms
05.{
06.    public class CustomComboBoxCell : GridDataCellElement
07.    {
08.
09.        public CustomComboBoxCell(GridViewColumn column, GridRowElement row) : base(column, row)
10.        {
11.        }
12.
13.        protected override Type ThemeEffectiveType
14.        {
15.            get { return typeof(GridDataCellElement); }
16.        }
17.
18.        public override bool IsCompatible(GridViewColumn data, object context)
19.        {
20.            return data is GenericDataColumn && context is GridDataRowElement;
21.        }
22.
23.    }
24.}

01.using System;
02.using Telerik.WinControls.UI;
03. 
04.namespace Inl.TelerikExtensions40.WinForms
05.{
06.    public class CustomTextBoxCell : GridDataCellElement
07.    {
08.        public CustomTextBoxCell(GridViewColumn column, GridRowElement row) : base(column, row)
09.        {
10.        }
11. 
12.        protected override Type ThemeEffectiveType
13.        {
14.            get { return typeof(GridDataCellElement); }
15.        }
16. 
17.        public override bool IsCompatible(GridViewColumn data, object context)
18.        {
19.            return data is GenericDataColumn && context is GridDataRowElement;
20.        }
21. 
22.    }
23. 
24.}

 

01.using System;
02.using System.Drawing;
03.using Telerik.WinControls.UI;
04. 
05.namespace Inl.TelerikExtensions40.WinForms
06.{
07.    public class CustomCheckBoxCell : GridDataCellElement
08.    {
09. 
10.        public RadCheckBoxElement radCheckBoxElement;
11. 
12.        public CustomCheckBoxCell(GridViewColumn column, GridRowElement row) : base(column, row)
13.        {
14.        }
15. 
16.        protected override void CreateChildElements()
17.        {
18.            base.CreateChildElements();
19.            radCheckBoxElement = new RadCheckBoxElement();
20.            radCheckBoxElement.ReadOnly = true;
21.            radCheckBoxElement.IsThreeState = true;
22.            Children.Add(this.radCheckBoxElement);
23.        }
24. 
25.        protected override SizeF ArrangeOverride(SizeF finalSize)
26.        {
27.            SizeF size = base.ArrangeOverride(finalSize);
28.            this.radCheckBoxElement.Arrange(new RectangleF((finalSize.Width - this.radCheckBoxElement.DesiredSize.Width) / 2f, (finalSize.Height - this.radCheckBoxElement.DesiredSize.Height) / 2f, this.radCheckBoxElement.DesiredSize.Width, this.radCheckBoxElement.DesiredSize.Height));
29.            return size;
30.        }
31. 
32.        protected override void SetContentCore(object value)
33.        {
34.            if (this.Value != null && !object.ReferenceEquals(this.Value, DBNull.Value))
35.            {
36.                if (value.ToString() == "Indeterminate")
37.                {
38.                    radCheckBoxElement.ToggleState = Telerik.WinControls.Enumerations.ToggleState.Indeterminate;
39.                }
40.                else if (value.ToString() == "On")
41.                {
42.                    radCheckBoxElement.ToggleState = Telerik.WinControls.Enumerations.ToggleState.On;
43.                }
44.                else
45.                {
46.                    radCheckBoxElement.ToggleState = Telerik.WinControls.Enumerations.ToggleState.Off;
47.                }
48.            }
49.            else
50.            {
51.                radCheckBoxElement.ToggleState = Telerik.WinControls.Enumerations.ToggleState.Indeterminate;
52.            }
53.        }
54. 
55.        protected override Type ThemeEffectiveType
56.        {
57.            get { return typeof(GridDataCellElement); }
58.        }
59. 
60.        public override bool IsCompatible(GridViewColumn data, object context)
61.        {
62.            return data is GenericDataColumn && context is GridDataRowElement;
63.        }
64.    }
65.}

 

 

01.
 using Inl.TelerikExtensions40.WinForms;
02.using System;
03.using Telerik.WinControls.UI;
04. 
05.namespace Inl.TelerikExtensions40.Tests
06.{
07.    public partial class FrmGridView : Telerik.WinControls.UI.RadForm
08.    {
09.        public FrmGridView()
10.        {
11.            InitializeComponent();
12.        }
13. 
14.        private void btnExport_Click(object sender, EventArgs e)
15.        {
16.            Inl.TelerikExtensions40.WinForms.RadGridView.Export(dgvCustomer);
17.        }
18. 
19.        private void dgvCustomer_CellFormatting(object sender, CellFormattingEventArgs e)
20.        {
21.            var costumer = (DataSource.Customer)e.Row.DataBoundItem;
22.            if (e.Column.GetType().Name == nameof(GenericDataColumn))
23.            {
24.                ((GenericDataColumn)e.Column).SetType(costumer.TipoDeValor, e.Row);
25.            }
26.        }
27. 
28.        private void dgvCustomer_DataBindingComplete(object sender, GridViewBindingCompleteEventArgs e)
29.        {
30.            dgvCustomer.TableElement.Update(Telerik.WinControls.UI.GridUINotifyAction.Reset);
31.        }
32. 
33.        private void FrmGridView_Load(object sender, EventArgs e)
34.        {
35.            customerBindingSource.DataSource = DataSource.Customer.GetList(1000);
36.            customerBindingSource.ResetBindings(false);
37.            WinForms.RadGridView.EnableBetterSearchRow(dgvCustomer);
38.        }
39.    }
40.}

 

01.using System.Drawing;
02.using Telerik.WinControls;
03.using Telerik.WinControls.UI;
04. 
05.namespace Inl.TelerikExtensions40.WinForms
06.{
07.    class CustomCheckBoxEditor : BaseGridEditor
08.    {
09.        public override object Value
10.        {
11.            get
12.            {
13.                var element = (RadCheckBoxElement)this.EditorElement;
14.                return element.ToggleState.ToString();
15.            }
16. 
17.            set
18.            {
19.                var element = (RadCheckBoxElement)this.EditorElement;
20.                if (value.ToString() == "Indeterminate")
21.                {
22.                    element.ToggleState = Telerik.WinControls.Enumerations.ToggleState.Indeterminate;
23.                }
24.                else if (value.ToString() == "On")
25.                {
26.                    element.ToggleState = Telerik.WinControls.Enumerations.ToggleState.On;
27.                }
28.                else
29.                {
30.                    element.ToggleState = Telerik.WinControls.Enumerations.ToggleState.Off;
31.                }
32.            }
33.        }
34.        protected override RadElement CreateEditorElement()
35.        {
36.            return new RadCheckBoxElement() { IsThreeState = true, Alignment = ContentAlignment.MiddleCenter, CheckAlignment = ContentAlignment.MiddleCenter };
37.        }
38.    }
39.}
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 06 Jul 2017, 09:04 AM
Hello Inelcis, 

Thank you for writing back. 

The provided sample code snippet is greatly appreciated. In the IsCompatible method, each of the cell elements returns true if the column is GenericDataColumn. This means that all of the columns are compatible with each other. I would recommend you to add a condition for the column's name as well. Thus, the cell element will be compatible only with one specific column. In addition, create one custom GridDataCellElement that will be used for default cell. In its IsCompatible method, this default cell should be compatible with all columns except the custom ones.

I hope this information helps. If you have any additional questions, please let me know. 

Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Inelcis
Top achievements
Rank 1
answered on 06 Jul 2017, 09:52 AM

Hi again Dess,

Thank you for everything so far.

I was left a bit confused so i'm just making sure but:

"This means that all of the columns are compatible with each other. I would recommend you to add a condition for the column's name as well."

Did you mean all of the cells are compatible with each other?

"In its IsCompatible method, this default cell should be compatible with all columns except the custom ones."

I'm completly lost on this one.

 

If it's not asking too much, some snippets would be extremely appreciated.

Thank you again

 

0
Accepted
Dess | Tech Support Engineer, Principal
Telerik team
answered on 06 Jul 2017, 10:49 AM
Hello Inelcis, 

Thank you for writing back. 

Firstly, I would like to note that RadGridView offers GridViewCheckBoxColumn which displays and allows editing of boolean data. The values are shown as checkboxes and allow the user to set or clear the check boxes to toggle the underlying boolean data values. Additional information is available here: http://docs.telerik.com/devtools/winforms/gridview/columns/column-types/gridviewcheckboxcolumn

An alternative solution would be to skip creating custom cells, but handle the EditorRequired event and specify what editor to be used. The following help article is quite useful on this topic: http://docs.telerik.com/devtools/winforms/gridview/editors/how-to/change-the-active-editor-depending-on-the-cell-value-type.

I have prepared a sample project for your reference using your code snippets. When you perform scrolling, everything works as expected.

I hope this information helps. If you have any additional questions, please let me know. 

 Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Inelcis
Top achievements
Rank 1
answered on 06 Jul 2017, 11:24 AM

Yes, but the main goal with creating this GenericColumn is to use different object types, on the same column.

I noticed something on the sample project you sent me that used the create cell event.

Using the type being bound to the column i create the specific celltype i wish and it seems to be working properly, i'm also adding your tip on the generic cell.

Will just perform a couple more tests during the day, and if nothing rises up i'll come back to mark the question as answered.

 

Again, thank you for everything Dess, much appreciated.

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 07 Jul 2017, 09:13 AM
Hello Inelcis, 

Thank you for writing back. 

I am glad that the provided sample project was useful. Feel free to test as long as you need. 

If you have any additional questions, please let me know. 

Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Inelcis
Top achievements
Rank 1
answered on 07 Jul 2017, 05:05 PM

Hi Dess,

Thank you so much for the help. Every test i've run so far as went well.

I'm marking this question as answered, but on a side note and as a last question: Is there any way i can override the createcell event: on the cell level or column level? wanted to keep as much code as possible 'under the hood' but i know its a longshot.

 

Again, thanks for everything.

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 10 Jul 2017, 09:56 AM
Hello Inelcis, 

Thank you for writing back. 

The CreateCell event is at RadGridView level. You can't switch it to column or cell level. This event is purposed to be fired when the grid creates the visual cell elements and it is necessary to provide the cell type that needs to be used considering the row and column.

I hope this information helps. If you have any additional questions, please let me know. 

Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
GridView
Asked by
Inelcis
Top achievements
Rank 1
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Inelcis
Top achievements
Rank 1
Share this question
or