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
12 Answers, 1 is accepted
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
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.
- How to Apply Format (add 2 decimal) on the Value.
- If I Resize the ROW height, then Custom Cell contents not resized accordingly.(See attached 2nd Image).
- Both left and right Button width is not equal. While Both Buttons was added to StackLayoutelEment with the same size.
- 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.
Question # 2 have be resoled by adding the line code snippet. (see Attached)
container.StretchVertically =
true
;
Others are still required to answer.
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
Perfect Solution.
Thank you very much.
How to Handle radButtonElement Click Event in UI.
Please give any example according to Code provided by you.
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
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.
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
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.
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
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