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

Add 2 buttons dynamically and set there visibility by checking the values of another column in grdi view

11 Answers 273 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Fazal
Top achievements
Rank 1
Fazal asked on 02 Oct 2010, 04:14 PM
hi all,

i am using telerik grid view in windows form application. i needed to to add two buttons in the command column dynamically. and then according to the values of some other column i can make any of the button invisible.
i was able to add a column with 2 buttons. but when i made any of them invisible it shows unexpected behavior. the adding of buttons and making them visible or not, only works fine for the rows that are present on the current display screen. if i scroll down then it makes the button invisible or visible in other rows. i am stuck. please help.
i am using function

private void radGWOrderSelection_CreateCell(object sender, GridViewCreateCellEventArgs e)
        {
            if (e.Column.Name == "Replace")
            {
                GridViewCommandColumn dataColumn = (GridViewCommandColumn)e.Column;
                if (e.Row is GridDataRowElement && dataColumn != null)
                {                

                    CustomGridDataCell cell = new CustomGridDataCell(e.Column, e.Row);
                    e.CellType = typeof(CustomGridDataCell);
                    e.CellElement = cell;
 
 
                    cell.ButtonOne.Visibility = ElementVisibility.Hidden;
                    cell.ButtonClick += new EventHandler(cell_ButtonClick);
 
                    cell.ButtonOne.Visibility = ElementVisibility.Hidden;
                    cell.ButtonClick += new EventHandler(cell_ButtonClick);
 
                    cell.CommandButton.Dispose();
 
                }
            }
        }

if i put a breakpoint it only executes 14 times which is the number of visible rows in the grid.

there is also a custom class CustomGridDataCell

11 Answers, 1 is accepted

Sort by
0
Emanuel Varga
Top achievements
Rank 1
answered on 03 Oct 2010, 08:49 AM
Hello Fazal,

The problem you are experiencing here is called scrambled values for cells, and this happens because when just handling the CreateCell event you are not taking into consideration the fact that the grid (in order to increase performance) reuses previous cells. Another problem with this aproach would be the fact that if you would try moving that column you would see some very interesting things :).

Please take a look at this following articles that will show how to use custom elements inside a cell, for example this KB article. It demonstrates how to handle radio buttons in RadGridView. using a custom column, for this article i've made some suggestions and additions, here(http://www.telerik.com/community/forums/winforms/gridview/toggle-state-of-radiobuttons-in-radgridviewcolumn.aspx) (sorry hyperlink manager down...) , also at the end of this post it is specified how to define a custom column.

This help article describes how to access and modify cell values. I hope this helps.

Hope this helps, if you have any more questions please do not hesitate to say so,

Best Regards,
Emanuel Varga

0
Fazal
Top achievements
Rank 1
answered on 03 Oct 2010, 06:29 PM
Hi,

Thanks for the help.
I have tried this but i have an issue that it shows me only one button in the gridview column. and when i scroll up and down it gives me exception that
Index out of range the number should be non-negative.
0
Emanuel Varga
Top achievements
Rank 1
answered on 03 Oct 2010, 06:34 PM
Hello Fazal,

Did you follow my directions in the article I've mentioned?

If you are using a CustomCellProvider and a custom cell it should be working, and you should NOT be using the CreateCell event, that is a very bad idea if you are using more rows than the visible rows...

If you are using these, please post a short example here, and i will help you further, but please try paying attention this page:http://www.telerik.com/community/forums/winforms/gridview/toggle-state-of-radiobuttons-in-radgridviewcolumn.aspx

Best Regards,
Emanuel Varga
0
Accepted
Emanuel Varga
Top achievements
Rank 1
answered on 03 Oct 2010, 07:07 PM
Hello again Fazal,

I've prepared a short application as a proof of concept, please let me know if you need anything else:

namespace TestCustomCellWProvider
{
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    using Telerik.WinControls.UI;
 
    public partial class Form1 : Form
    {
        private RadGridView radGridView1;
 
        public Form1()
        {
            InitializeComponent();
            this.Size = new Size(500, 400);
            this.Load += new EventHandler(Form1_Load);
        }
 
        void Form1_Load(object sender, EventArgs e)
        {
            radGridView1 = new RadGridView();
            radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
            radGridView1.Dock = DockStyle.Fill;
            this.radGridView1.TableElement.CellElementProvider = new CustomCellProvider(this.radGridView1.TableElement);
 
            this.Controls.Add(radGridView1);
 
            radGridView1.DataSource = new TestsCollection(1000);
        }
    }
 
    #region Helpers
 
    internal class Test
    {
        public int Id { get; set; }
 
        public string OtherColumn { get; set; }
 
        public string CustomColumn { get; set; }
 
        public Test(int id, string otherColumn, string customColumn)
        {
            this.Id = id;
            this.OtherColumn = otherColumn;
            this.CustomColumn = customColumn;
        }
    }
 
    internal class TestsCollection : BindingList<Test>
    {
        public TestsCollection(int noItems)
        {
            for (int i = 0; i < noItems; i++)
            {
                this.Add(new Test(i, "item" + i, i.ToString()));
            }
        }
    }
 
    #endregion Helpers
 
    #region Custom Cell Provider & Custom Cell
 
    public class CustomCellProvider : CellElementProvider
    {
        public CustomCellProvider(GridTableElement tableElement)
            : base(tableElement)
        {
        }
 
        public override IVirtualizedElement<GridViewColumn> CreateElement(GridViewColumn data, object context)
        {
            var dataRow = context as GridDataRowElement;
            if (data.Name == "CustomColumn" && dataRow != null)
            {
                var cell = new CustomCell(data, dataRow);
                return cell;
            }
 
            return base.CreateElement(data, context);
        }
 
        public override bool IsCompatible(
            IVirtualizedElement<GridViewColumn> element, GridViewColumn data, object context)
        {
            if (data.Name == "CustomColumn" &&
                context is GridDataRowElement)
            {
                return element is CustomCell;
            }
 
            if (element is CustomCell)
            {
                return false;
            }
 
            return base.IsCompatible(element, data, context);
        }
    }
 
    public class CustomCell : GridDataCellElement
    {
        protected override Type ThemeEffectiveType
        {
            get
            {
                return typeof(GridDataCellElement);
            }
        }
 
        public RadButtonElement Button1Element
        {
            get;
            set;
        }
 
        public RadButtonElement Button2Element
        {
            get;
            set;
        }
 
        public CustomCell(GridViewColumn column, GridRowElement row)
            : base(column, row)
        {
        }
 
        protected override void CreateChildElements()
        {
            var button1 = new RadButtonElement();
            button1.Text = "Button1";
            button1.Margin = new Padding(0, 2, 0, 0);
            button1.MinSize = new Size(20, 20);
            button1.ImageAlignment = ContentAlignment.MiddleCenter;
            button1.Click += new EventHandler(button1_Click);
            Button1Element = button1;
 
            var button2 = new RadButtonElement();
            button2.Text = "Button2";
            button2.Margin = new Padding(0, 2, 0, 0);
            button2.MinSize = new Size(20, 20);
            button2.ImageAlignment = ContentAlignment.MiddleCenter;
            button2.Click += new EventHandler(button2_Click);
            Button2Element = button2;
 
            this.Children.Add(button1);
            this.Children.Add(button2);
 
            this.CreateTextParams();
            base.CreateChildElements();
        }
 
        void button2_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Button2 pressed");
        }
 
        void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Button1 pressed");
        }
 
        /// <summary>
        /// Sets the actual text of the cell.
        /// </summary>
        /// <param name="value"></param>
        protected override void SetContentCore(object value)
        {
            if (this.Value != null && this.Value != DBNull.Value)
            {
                Button1Element.Text = "Button1:" + value;
                Button2Element.Text = "Button2:" + value;
                // set elements based on value
            }
        }
 
        protected override SizeF ArrangeOverride(SizeF finalSize)
        {
            if (this.Children.Count == 2)
            {
                this.Children[0].Arrange(
                    new RectangleF(
                        0,
                        (finalSize.Height / 2) - (this.Children[0].DesiredSize.Height / 2 + 1),
                        finalSize.Width / 2 - 1,
                        this.Children[0].DesiredSize.Height));
                this.Children[1].Arrange(
                    new RectangleF(finalSize.Width / 2 + 1, (finalSize.Height / 2) - (this.Children[0].DesiredSize.Height / 2 + 1), finalSize.Width / 2 - 1, this.Children[1].DesiredSize.Height));
            }
 
            this.UpdateInfo();
 
            return finalSize;
        }
    }
 
    #endregion Custom Cell Provider & Custom Cell
}

Hope this helps, if you have any more questions please do not hesitate to say so,

Best Regards,
Emanuel Varga
0
Fazal
Top achievements
Rank 1
answered on 03 Oct 2010, 09:40 PM
Hi Emanuel,

thanks a lot for the code. It is working fine. i was successful in doing so by the help of the previous code you gave. but my issue is to hide buttons according to the values and when i do so in the function SetContentCore()
protected override void SetContentCore(object value)
        {
            if(this.Value != null&& this.Value != DBNull.Value)
            {
                if (value.ToString() == "77" || value.ToString() == "1" || value.ToString() == "3")
                {
                    Button1Element.Visibility = Telerik.WinControls.ElementVisibility.Hidden;
                    Button2Element.Text = "Button2:" + value;
                }
                else
                {
                    Button1Element.Text = "Button1:" + value;
                    Button2Element.Text = "Button2:" + value;
                }
            }
        }

it hides the button. but when i scroll down it shows me rows having no button which i haven't done. thanks for your help.
0
Accepted
Emanuel Varga
Top achievements
Rank 1
answered on 03 Oct 2010, 09:53 PM
Hello again Fazal,

You forgot to show the button again on else, because of cells being reused, you hide the button once, and when that cell is being reused, it will show up as hidden, so you should use it like this:
protected override void SetContentCore(object value)
        {
            if (this.Value != null && this.Value != DBNull.Value)
            {
                if (this.Value != null && this.Value != DBNull.Value)
                {
                    if (value.ToString() == "77" || value.ToString() == "1" || value.ToString() == "3")
                    {
                        Button1Element.Visibility = Telerik.WinControls.ElementVisibility.Hidden;
                        Button2Element.Text = "Button2:" + value;
                    }
                    else
                    {
                        Button1Element.Visibility = Telerik.WinControls.ElementVisibility.Visible;
                        Button1Element.Text = "Button1:" + value;
                        Button2Element.Text = "Button2:" + value;
                    }
                }
            }
        }

Hope this helps, if you have any more questions please do not hesitate to say so,

Best Regards,
Emanuel Varga
0
Fazal
Top achievements
Rank 1
answered on 03 Oct 2010, 10:08 PM
thanks a lot. thank you once again for your help. it resolved my headache 100 percent. thank you
0
Robert
Top achievements
Rank 1
answered on 07 Mar 2011, 08:20 PM
Hi,

I've implemented a custom row with a custom cell element, following the advice in the referenced article; for my application, I have placed a button in some cells and text in other cells, depending on the cell's content.  It all works fine in a single-level grid, but in a hierarchical grid, the UI becomes corrupted when the user expands and collapses rows; specifically, buttons begin to appear in row that should only have text.

My custom grid classes are copied below.  I'd appreciate any suggestions.

public class GridHouseholdCellElement : GridDataCellElement
    {
        private Color borderColor = System.Drawing.ColorTranslator.FromHtml("#D1E1F5");

        public GridHouseholdCellElement(GridViewColumn column, GridRowElement row)
            : base(column, row)
        {
        }

        protected override void CreateChildElements()
        {
            base.CreateChildElements();

            RadButtonElement button = new RadButtonElement("Create New Household");
            button.DisplayStyle = DisplayStyle.Text;
            button.Size = new Size(127, 20);
            button.AutoSize = false;
            button.Visibility = ElementVisibility.Hidden;
            this.Children.Add(button);
            this.Alignment = ContentAlignment.MiddleCenter;
            this.TextAlignment = ContentAlignment.MiddleCenter;
        }

        protected override void SetContentCore(object value)
        {
            if (this.Value != null && this.Value != DBNull.Value && value.ToString() == "<create>")
            {
                this.Children[0].Visibility = ElementVisibility.Visible;
                this.Text = string.Empty;
            }
            else
                this.Text = value.ToString();
        }
       
    }

    public class HouseholdColumn : GridViewDataColumn
    {
        public HouseholdColumn(string fieldName)
            : base(fieldName)
        {
        }

        public override Type GetCellType(GridViewRowInfo row)
        {
            if (row is GridViewDataRowInfo)
            {
                return typeof(GridHouseholdCellElement);
            }
            return base.GetCellType(row);
        }
    }
0
Martin Vasilev
Telerik team
answered on 10 Mar 2011, 02:14 PM
Hello Robert,

Thank you for writing.

It looks like you have forgotten to hide the button in an else clause in SetContentCore method:
protected override void SetContentCore(object value)
        {
            if (this.Value != null && this.Value != DBNull.Value && value.ToString() == "<create>")
            {
                this.Children[0].Visibility = ElementVisibility.Visible;
                this.Text = string.Empty;
            }
            else
            {
                this.Children[0].Visibility = ElementVisibility.Hidden;
                this.Text = value.ToString();
            }
        }

Let me know if you still experience any issues.

Greetings,
Martin Vasilev
the Telerik team
Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
0
Frank
Top achievements
Rank 1
answered on 26 Apr 2011, 01:06 PM
I'm curious as to why you advise against using the CreateCell event when implementing a custom cell. I'm working on a project where I'm creating a custom cell with a RadCheckBoxElement and am using some other articles/threads in the forums where overriding the CreateCell event is suggested. Here is an example:

http://www.telerik.com/community/forums/winforms/combobox-and-listbox/some-question-on-grideview.aspx

Thanks,

Frank
0
Alexander
Telerik team
answered on 29 Apr 2011, 10:52 AM
Hello Frank,

The older versions of RadGridView provide UI virtualization only for the rows of the control. In the Q2 2010 release is introduced columns virtualization. It is possible for a custom cell to be reused by other columns after horizontal scrolling, grouping and other operations. You can prevent this by using custom cells in a custom column, making them compatible only for this column. Please review the following help article to learn more for creating custom cells.

I hope the above information helps.

Best regards,
Alexander
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
GridView
Asked by
Fazal
Top achievements
Rank 1
Answers by
Emanuel Varga
Top achievements
Rank 1
Fazal
Top achievements
Rank 1
Robert
Top achievements
Rank 1
Martin Vasilev
Telerik team
Frank
Top achievements
Rank 1
Alexander
Telerik team
Share this question
or