GridView Custom Cell Column

13 posts, 2 answers
  1. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 13 Sep 2019 Link to this post

    Dear Admins.
    Using Telerik Winform UI R2 2019 SP1.
    I'm trying to add Custom Cell in gridview column. (want to add 2 Buttons and a TextBox)
    What i have did is 

    public class CustomCellElement : GridDataCellElement
    {
        private RadButtonElement radButtonElement;
        private RadButtonElement radButtonElement1;
        private RadTextBoxElement radTextBoxElement;
     
        public CustomCellElement(GridViewColumn column, GridRowElement row) : base(column, row)
        {
        }
     
        protected override void CreateChildElements()
        {
            base.CreateChildElements();
     
            radButtonElement = new RadButtonElement
            {
                Text = "-",
                Margin = new Padding(1, 1, 2, 1)
     
            };
            radButtonElement.Click += new EventHandler(radButtonElement_Click);
            this.Children.Add(radButtonElement);
     
            this.radTextBoxElement = new RadTextBoxElement
            {
                Margin = new Padding(1, 1, 1, 1),
                TextAlign = HorizontalAlignment.Right
            };
            this.Children.Add(radTextBoxElement);
     
            radButtonElement1 = new RadButtonElement
            {
                Text = "+",
                Margin = new Padding(2, 1, 1, 1)
            };
            radButtonElement1.Click += new EventHandler(radButtonElement1_Click);
            this.Children.Add(radButtonElement1);
        }
     
        private void radButtonElement_Click(object sender, EventArgs e)
        {
            int value = Convert.ToInt32(radTextBoxElement.Text) - 1;
     
            if (value > 0)
                radTextBoxElement.Text = Convert.ToString(value);
        }
     
        private void radButtonElement1_Click(object sender, EventArgs e)
        {
            int value = Convert.ToInt32(radTextBoxElement.Text) + 1;
     
            if (value > 0)
                radTextBoxElement.Text = Convert.ToString(value);
        }
     
        protected override void DisposeManagedResources()
        {
            radButtonElement.Click -= new EventHandler(radButtonElement_Click);
            radButtonElement1.Click -= new EventHandler(radButtonElement1_Click);
            base.DisposeManagedResources();
        }
     
        protected override Type ThemeEffectiveType
        {
            get
            {
                return typeof(GridDataCellElement);
            }
        }
     
        protected override SizeF ArrangeOverride(SizeF finalSize)
        {
            if (this.Children.Count == 3)
            {
                float textBoxWidth = finalSize.Width - radButtonElement.DesiredSize.Width - radButtonElement1.DesiredSize.Width;
     
                RectangleF buttonRect = new RectangleF(0, 0, radButtonElement.DesiredSize.Width, finalSize.Height);
                RectangleF textBoxRect = new RectangleF(radButtonElement.DesiredSize.Width - 1, 0, textBoxWidth - 1, finalSize.Height);
                RectangleF button1Rect = new RectangleF(textBoxWidth + radButtonElement.DesiredSize.Width - 1, 0, radButtonElement1.DesiredSize.Width, finalSize.Height);
     
                this.Children[0].Arrange(buttonRect);
                this.Children[1].Arrange(textBoxRect);
                this.Children[2].Arrange(button1Rect);
     
            }
     
            return finalSize;
        }
    }
    public class CustomColumn : GridViewDataColumn
    {
        public CustomColumn() : base()
        { }
     
        public CustomColumn(string fieldName) : base(fieldName)
        {
        }
        public CustomColumn(string uniqueName, string fieldName) : base(uniqueName, fieldName)
        {
     
        }
     
        public override Type GetCellType(GridViewRowInfo row)
        {
            if (row is GridViewDataRowInfo)
            {
                return typeof(CustomCellElement);
            }
            return base.GetCellType(row);
        }
    }

     

    and How a Add it  GridView

    CustomColumn customColumn = new CustomColumn
    {
        Name = "Qty",
        FieldName = "Qty",
        HeaderText = "Quantity",
        Width = 150,
        HeaderTextAlignment = ContentAlignment.MiddleRight,
        TextAlignment = ContentAlignment.MiddleRight
    };
     
    radGridView1.MasterTemplate.Columns.Add(customColumn);

     

     

    I'm Facing Display problem Please see Image.

    Buttons are not displaying properly, cutting the sides. TextBox should be according to the height of GridView cell you can see empty area at the bottom.

    How to get and set the value of text box. when row is adding directly to grid.

    Please note that the Gridview AllowAddNewRow & AllowEditRow is set to False.(adding Row to GridView Programatically)

    But I can Still change the value in the Textbox(Editing to textbox should be disabled.)

    Apply the format like other column(please see image).

     

    Thank you

    Kashif

  2. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3754 posts

    Posted 18 Sep 2019 Link to this post

    Hello, Kashif,

    The provided sample code snippet is greatly appreciated. Firstly, I would like to note that RadTextBoxElement internally uses the MS TextBox control. Using controls in grid cells may slow down the scrolling and will cause visual glitches as they do not support clipping. A better option would be using RadTextBoxControlElement. However, you mentioned that editing in text-box should be disabled. Hence, you don't need to use an input box, but an element to visualize a value. LightVisualElement is suitable for this case.

    I have modified the code snippet which result is illustrated in the attached gif file. I hope it is suitable for your scenario:

            public RadForm1()
            {
                InitializeComponent();
                CustomColumn customColumn = new CustomColumn
                {
                    Name = "Qty",
                    FieldName = "Qty",
                    HeaderText = "Quantity",
                    Width = 150,
                    HeaderTextAlignment = ContentAlignment.MiddleRight,
                    TextAlignment = ContentAlignment.MiddleRight
                };
    
                radGridView1.MasterTemplate.Columns.Add(customColumn);
    
                for (int i = 0; i < 20; i++)
                {
                    this.radGridView1.Rows.Add(i);
                }
            }
        }
    
        public class CustomCellElement : GridDataCellElement
        {
            StackLayoutElement container = new StackLayoutElement();
            private RadButtonElement radButtonElement;
            private RadButtonElement radButtonElement1;
            private LightVisualElement radTextBoxElement;
    
            public CustomCellElement(GridViewColumn column, GridRowElement row) : base(column, row)
            {
            }
    
            protected override void CreateChildElements()
            {
                base.CreateChildElements();
                container.Orientation = Orientation.Horizontal;
                container.StretchHorizontally = true;
                radButtonElement = new RadButtonElement
                {
                    Text = "-",
                    Margin = new Padding(1, 1, 2, 1),
                    MaxSize = new Size(20,0),
                    StretchHorizontally = false
                };
                radButtonElement.Click += new EventHandler(radButtonElement_Click);
                container.Children.Add(radButtonElement);
    
                this.radTextBoxElement = new LightVisualElement
                {
                    Margin = new Padding(1, 1, 1, 1),
                    StretchHorizontally = true
                };
                this.radTextBoxElement.TextChanged+=radTextBoxElement_TextChanged;
                
                container.Children.Add(radTextBoxElement);
    
                radButtonElement1 = new RadButtonElement
                {
                    Text = "+",
                    Margin = new Padding(2, 1, 1, 1),
                    MaxSize = new Size(20, 0),
                    StretchHorizontally = false
                };
                radButtonElement1.Click += new EventHandler(radButtonElement1_Click);
                container.Children.Add(radButtonElement1);
    
                this.Children.Add(container);
            }
    
            private void radTextBoxElement_TextChanged(object sender, EventArgs e)
            {
                if (this.Value!=this.radTextBoxElement.Text)
                {
                    this.Value = this.radTextBoxElement.Text;
                }
               
            }
    
            private void radButtonElement_Click(object sender, EventArgs e)
            {
                int value = Convert.ToInt32(radTextBoxElement.Text) - 1;
    
                if (value > 0)
                    radTextBoxElement.Text = Convert.ToString(value);
            }
    
            private void radButtonElement1_Click(object sender, EventArgs e)
            {
                int value = Convert.ToInt32(radTextBoxElement.Text) + 1;
    
                if (value > 0)
                    radTextBoxElement.Text = Convert.ToString(value);
            }
    
            protected override void DisposeManagedResources()
            {
                radButtonElement.Click -= new EventHandler(radButtonElement_Click);
                radButtonElement1.Click -= new EventHandler(radButtonElement1_Click);
                base.DisposeManagedResources();
            }
    
            protected override Type ThemeEffectiveType
            {
                get
                {
                    return typeof(GridDataCellElement);
                }
            }
    
            protected override void SetContentCore(object value)
            {
                base.SetContentCore(value);
                this.DrawText = false;
                this.radTextBoxElement.Text = this.Value + "";
            }
        }
    
        public class CustomColumn : GridViewDataColumn
        {
            public CustomColumn() : base()
            {
            }
    
            public CustomColumn(string fieldName) : base(fieldName)
            {
            }
    
            public CustomColumn(string uniqueName, string fieldName) : base(uniqueName, fieldName)
            {
            }
    
            public override Type GetCellType(GridViewRowInfo row)
            {
                if (row is GridViewDataRowInfo)
                {
                    return typeof(CustomCellElement);
                }
                return base.GetCellType(row);
            }
        }

    I hope this information helps. If you need any further assistance please don't hesitate to contact me. 

    Regards,
    Dess | Tech Support Engineer, Sr.
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  3. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 18 Sep 2019 in reply to Kashif Link to this post

    Thank you very much Dess.

    The Change in you have suggested is working fine.

    When i apply the Code, following code snippet was giving the warning.(see attached Image)

    private void radTextBoxElement_TextChanged(object sender, EventArgs e)
    {
          if (this.Value!=this.radTextBoxElement.Text)
          {
              this.Value = this.radTextBoxElement.Text;
          }
                
     }

    then i Change it according to information suggested.

    private void radTextBoxElement_TextChanged(object sender, EventArgs e)
    {
        if ((string)Value != radTextBoxElement.Text)
        {
            this.Value = this.radTextBoxElement.Text;
        }
    }

     

    Some more information required.

    1. How to Apply Format (add 2 decimal) on the Value. 
    2. If I Resize the ROW height, then Custom Cell contents not resized accordingly.(See attached 2nd Image).
    3. Both left and right Button width is not equal. While Both Buttons was added to StackLayoutelEment with the same size.
    4. I want to change the Value of other column when any (Plus or Minus) button clicked. how to handle the CustomCell Click event in UI.

     

     

  4. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 18 Sep 2019 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    Question # 2 have be resoled by adding the  line code snippet. (see Attached)

    container.StretchVertically = true;

     

    Others are still required to answer.

  5. Answer
    Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3754 posts

    Posted 19 Sep 2019 Link to this post

    Hello, Kashif,  

    Although I don't obtain this warning on my end, the Value property is typeof(object) but the LightVisualElement.Text property is typeof(string). Casting the Value to string is a suitable solution to eliminate the warning. Please ensure that the Value is not null. Otherwise, you will obtain an exception. 

    As to the questions at hand, I will go straight to them:
    1. In order to format the decimal values you can use the String.Format option before updating the text in the LightVisualElement. Here is the modified code snippet:

     

        public class CustomCellElement : GridDataCellElement
        {
            StackLayoutElement container = new StackLayoutElement();
            private RadButtonElement radButtonElement;
            private RadButtonElement radButtonElement1;
            private LightVisualElement radTextBoxElement;
    
            public CustomCellElement(GridViewColumn column, GridRowElement row) : base(column, row)
            {
            }
    
            protected override void CreateChildElements()
            {
                base.CreateChildElements();
                container.Orientation = Orientation.Horizontal;
                container.StretchHorizontally = true;
                radButtonElement = new RadButtonElement
                {
                    Text = "-",
                    Margin = new Padding(1, 1, 2, 1),
                    MaxSize = new Size(20,0),
                    StretchHorizontally = false
                };
                radButtonElement.Click += new EventHandler(radButtonElement_Click);
                container.Children.Add(radButtonElement);
    
                this.radTextBoxElement = new LightVisualElement
                {
                    Margin = new Padding(1, 1, 1, 1),
                    StretchHorizontally = true
                };
                this.radTextBoxElement.TextChanged += radTextBoxElement_TextChanged;
                
                container.Children.Add(radTextBoxElement);
    
                radButtonElement1 = new RadButtonElement
                {
                    Text = "+",
                    Margin = new Padding(2, 1, 1, 1),
                    MaxSize = new Size(20, 0),
                    StretchHorizontally = false
                };
                radButtonElement1.Click += new EventHandler(radButtonElement1_Click);
                container.Children.Add(radButtonElement1);
    
                this.Children.Add(container);
            }
    
            private void radTextBoxElement_TextChanged(object sender, EventArgs e)
            {
                if (this.Value != this.radTextBoxElement.Text)
                {
                    decimal parsedValue = 0;
                    if (decimal.TryParse(this.radTextBoxElement.Text, out parsedValue))
                    {
                        this.radTextBoxElement.Text = String.Format("{0:N2}", parsedValue);  
    
                        this.Value = this.radTextBoxElement.Text;
                    }
                }
            }
    
            private void radButtonElement_Click(object sender, EventArgs e)
            {
                decimal value = Convert.ToDecimal(radTextBoxElement.Text) - 1;
    
                if (value > 0)
                    radTextBoxElement.Text = Convert.ToString(value);
            }
    
            private void radButtonElement1_Click(object sender, EventArgs e)
            {
                decimal value = Convert.ToDecimal(radTextBoxElement.Text) + 1;
    
                if (value > 0)
                    radTextBoxElement.Text = Convert.ToString(value);
            }
    
            protected override void DisposeManagedResources()
            {
                radButtonElement.Click -= new EventHandler(radButtonElement_Click);
                radButtonElement1.Click -= new EventHandler(radButtonElement1_Click);
                base.DisposeManagedResources();
            }
    
            protected override Type ThemeEffectiveType
            {
                get
                {
                    return typeof(GridDataCellElement);
                }
            }
    
            protected override void SetContentCore(object value)
            {
                base.SetContentCore(value);
                this.DrawText = false;
                if (this.Value != null)
                {
                    decimal val = 0;
                    if (decimal.TryParse(this.Value + "", out val))
                    {
                        this.radTextBoxElement.Text = String.Format("{0:N2}", val);  
                    }
                }
            }
        }

     

    2. Indeed, the StretchVertically property allows you to control whether to occupy the available height of the parent container or not.

    3. The Min/MaxSize properties of RadButtonElement allows you to apply a fixed size for the buttons if they are set to the same value.

    4. You can handle the RadButtonElement.Click event and adjust any other cell's value. Note that the RowInfo.Cells collection is suitable for accessing the desired cell and get the value you need to adjust according to the column's name.

    Note that most of the forum threads are reviewed by Telerik representatives and sometimes we address the questions asked by our customers in the forums as well. However, a post in the forum doesn't guarantee you a response from the Telerik support team. Moreover, threads are handled according to license and time of posting, so if it is an urgent problem, we suggest you use a support ticket, which would be handled before a forum thread.

    Thank you for your understanding.

    Regards,
    Dess | Tech Support Engineer, Sr.
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  6. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 19 Sep 2019 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    Perfect Solution.

    Thank you very much.

  7. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 22 Sep 2019 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    How to Handle radButtonElement Click Event in UI.

    Please give any example according to Code provided by you.

  8. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3754 posts

    Posted 23 Sep 2019 Link to this post

    Hello, Kashif,  

    Since the previously provided solution includes a custom implementation for the GridDataCellElement, you can subscribe to the RadButtonElement.Click event at run time as it is already available in the code snippet. You don't have access to the custom cell and its inner elements at design time. Hence, you can't handle their events in the UI.

    What is the exact requirement that you are trying to achieve? Maybe you can achieve it in another way. Once you provide with further details, we would be able to think about a suitable solution and assist you further. Thank you in advance.

    I am looking forward to your reply.

    Regards,
    Dess | Tech Support Engineer, Sr.
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  9. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 23 Sep 2019 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    Hello Dess,

    I have Multiple column the the Grid. When I Change the Qty, Its Amount Changes. i was using this Code.

    private void ChangeRowValues(string OperatorSymble)
     {
         int selectedIndex = this.GridViewSaleItems.MasterTemplate.Rows.IndexOf(this.GridViewSaleItems.CurrentRow);
         GridViewRowInfo SelectedRow = this.GridViewSaleItems.MasterTemplate.Rows[selectedIndex];
         double Qty = Convert.ToDouble(SelectedRow.Cells["QTY"].Value);
         double Sale_Rate = Convert.ToDouble(SelectedRow.Cells["SALE_RATE"].Value);
     
         if (OperatorSymble == "+")
             Qty += 1;
         else if (OperatorSymble == "-")
             Qty -= 1;
     
         if (Qty < 0)
             Qty = 0;
     
         SelectedRow.Cells["QTY"].Value = Qty;
         SelectedRow.Cells["AMOUNT"].Value = (Qty * Sale_Rate);
     }

     

    I was able to Change its Amount when Change the qty from other method.

    But when i change the Qty using its CustomCellElement (Plus or Minus) button. I can not capture/handle its click event in UI either through code or design time.

    I just Use this method in the Both (plus / minus) buttons to change the values accordingly.

    I think now it is clear from the above detail about my exact requirement.

     

  10. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3754 posts

    Posted 24 Sep 2019 Link to this post

    Hello, Kashif,   

    If you need to change the value of another cell on the same row when clicking the +/- buttons, you actually need to handle the RadGridView.CellValueChanged event. This event is fired whenever a cell value is updated. In the event arguments you have access to affected the row/column and new value. Thus, you can determine whether you changed the value of a specific cell that affects the values in other columns and update them accordingly. You can find below a sample code snippet:

            private void radGridView1_CellValueChanged(object sender, GridViewCellEventArgs e)
            {
                if (e.Column.Name=="Qty")
                {
                    e.Row.Cells["AMOUNT"].Value = "new value";
                }
            }

    I hope this information helps. If you need any further assistance please don't hesitate to contact me. 

     

    Regards,
    Dess | Tech Support Engineer, Sr.
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  11. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 24 Sep 2019 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    so there is no way to catch the click event in the UI.

    OR no any other method to handle the Row Values with the +/- Button's  Click Event.

  12. Answer
    Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3754 posts

    Posted 25 Sep 2019 Link to this post

    Hello, Kashif,   

    As it was previously noted you don't have access to the custom cell and its inner elements at design time. Hence, you can't handle their events in the UI. If you need to handle an event on RadGridView level, you may create a custom event for RadGridView and trigger it from the cell's +/- buttons' Click event. The following KB article demonstrates a sample approach how you can create a custom Pasted event in RadGridView. You can follow a similar approach into creating an event on RadGridView level: https://docs.telerik.com/devtools/winforms/knowledge-base/gridview-pasted-event

    Clicking the +/- buttons directly affects the cell's value and the CellValueChanged event is fired as a result of this. Could you please share with us your concerns about about using this event?

    I am looking forward to your reply.

    Regards,
    Dess | Tech Support Engineer, Sr.
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  13. Kashif
    Kashif avatar
    66 posts
    Member since:
    Jan 2019

    Posted 25 Sep 2019 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    I have achieved my required functionality using CellValueChanged event, and its working fine.

    Thank you for your great help.

    as for as about the Click event handling, it was just to add the knowledge.

     

    Thank you again

Back to Top