how can I do to create a column that is a GridViewTextBoxColumn with a button inside?
Like GridViewColumnBrowse, but I just need the Click event, I don't need the list.
Is it possible?
17 Answers, 1 is accepted
Thank you for writing.
One way to achieve this is to create a custom editor and add the button to it. Here is an example for this:
public class MyEditor : RadTextBoxEditor{ protected override Telerik.WinControls.RadElement CreateEditorElement() { return new MyTextElement(); } public override void BeginEdit() { base.BeginEdit(); string oldValue = this.Value.ToString(); this.EditorElement.Tag = oldValue; }}public class MyTextElement : RadTextBoxEditorElement{ public MyTextElement() { RadButtonElement button = new RadButtonElement(); button.Click += button_Click; button.Padding = new Padding(2, 0, 2, -2); button.Margin = new Padding(0, 0, 0, 0); button.Text = "..."; RadTextBoxItem tbItem = this.TextBoxItem; this.Children.Remove(tbItem); DockLayoutPanel dockPanel = new DockLayoutPanel(); dockPanel.Children.Add(button); dockPanel.Children.Add(tbItem); DockLayoutPanel.SetDock(tbItem, Telerik.WinControls.Layouts.Dock.Left); DockLayoutPanel.SetDock(button, Telerik.WinControls.Layouts.Dock.Right); this.Children.Add(dockPanel); } void button_Click(object sender, EventArgs e) { }}You can use the EditorRequired event to change the editor of a particular column:
void grid_EditorRequired(object sender, EditorRequiredEventArgs e){ if (e.EditorType == typeof(RadTextBoxEditor) && radGridView1.CurrentColumn.Name == "Name") { e.EditorType = typeof(MyEditor); }}Another approach is to create a custom cell. Detailed information about this is available here: Creating custom cells. Here is an example of a cell element which can be used with the custom column from the article:
class GridViewButtonCell : GridDataCellElement{ protected override Type ThemeEffectiveType { get { return typeof(GridDataCellElement); } } public GridViewButtonCell(GridViewColumn col, GridRowElement row) : base(col, row) { } RadButtonElement button; protected override void CreateChildElements() { base.CreateChildElements(); button = new RadButtonElement(); button.Text = "..."; button.StretchHorizontally = false; button.StretchVertically = false; this.Children.Add(button); } protected override SizeF ArrangeOverride(SizeF finalSize) { var result = base.ArrangeOverride(finalSize); var buttonRect = new RectangleF(finalSize.Width - (button.Size.Width + 2), 2, button.Size.Width, finalSize.Height); button.Arrange(buttonRect); return result; }}I hope this will be useful. Let me know if you have additional questions.
Regards,
Dimitar
Telerik by Progress
Thank you for reply, I adopted second way.
I followed this tutorial creating-custom-cells (same as yours).
But I dont' understand how it exposes Click event of my GridViewTextButtonColumn class.
Here my codes:
01.Public Class TextButtonCellElement02. Inherits GridDataCellElement03. 04. Public Sub New(ByVal column As GridViewColumn, ByVal row As GridRowElement)05. MyBase.New(column, row)06. End Sub07. 08. Private _RadTextBoxControl As RadTextBoxElement09. Private _RadButtonElement As RadButtonElement10. 11. Protected Overrides Sub CreateChildElements()12. MyBase.CreateChildElements()13. 14. _RadTextBoxControl = New RadTextBoxElement()15. Me.Children.Add(_RadTextBoxControl)16. 17. _RadButtonElement = New RadButtonElement18. _RadButtonElement.Text = "..."19. _RadButtonElement.Margin = New Windows.Forms.Padding(0, 1, 3, 1)20. AddHandler _RadButtonElement.Click, AddressOf _RadButtonElement_Click21. Me.Children.Add(_RadButtonElement)22. 23. End Sub24. 25. Protected Overrides Sub DisposeManagedResources()26. RemoveHandler _RadButtonElement.Click, AddressOf _RadButtonElement_Click27. MyBase.DisposeManagedResources()28. End Sub29. 30. Protected Overrides Function ArrangeOverride(ByVal finalSize As SizeF) As SizeF31. If Me.Children.Count = 2 Then32. Dim progressBarWidth As Single = finalSize.Width - _RadButtonElement.DesiredSize.Width33. Dim progressBarRect As New RectangleF(0, 0, progressBarWidth - 1, finalSize.Height)34. Dim buttonRect As New RectangleF(progressBarWidth + 1, 0, _RadButtonElement.DesiredSize.Width, finalSize.Height)35. Me.Children(0).Arrange(progressBarRect)36. Me.Children(1).Arrange(buttonRect)37. End If38. Return finalSize39. End Function40. 41. Public Shadows Event Click(sender As Object, e As EventArgs)42. Private Sub _RadButtonElement_Click(sender As Object, e As EventArgs)43. RaiseEvent Click(sender, e)44. End Sub45. 46. Protected Overrides Sub SetContentCore(ByVal value As Object)47. If Me.Value IsNot Nothing AndAlso Me.Value IsNot DBNull.Value Then48. Me._RadTextBoxControl.Text = CStr(Me.Value)49. End If50. End Sub51. 52. Protected Overrides ReadOnly Property ThemeEffectiveType() As Type53. Get54. Return GetType(GridDataCellElement)55. End Get56. End Property57. 58. Public Overrides Function IsCompatible(ByVal data As GridViewColumn, ByVal context As Object) As Boolean59. Return TypeOf data Is GridViewTextButtonColumn AndAlso TypeOf context Is GridDataRowElement60. End Function61. 62.End Class63. 64.Public Class GridViewTextButtonColumn65. Inherits GridViewDataColumn66. Public Sub New(ByVal fieldName As String)67. MyBase.New(fieldName)68. 69. End Sub70. 71. Private _GridViewRowInfo As GridViewRowInfo72. Public Property GridViewRowInfo() As GridViewRowInfo73. Get74. Return _GridViewRowInfo75. End Get76. Set(ByVal value As GridViewRowInfo)77. _GridViewRowInfo = value78. End Set79. End Property80. 81. Public Sub Click(sender As Object, e As EventArgs)82. Throw New NotImplementedException()83. End Sub84. 85. Public Overrides Function GetCellType(ByVal row As GridViewRowInfo) As Type86. 87. If TypeOf row Is GridViewDataRowInfo Then88. Return GetType(TextButtonCellElement)89. End If90. Return MyBase.GetCellType(row)91. 92. _GridViewRowInfo = row93. End Function94.End ClassStrange, I'm trying to populate rows (unbound mode), but I don't find specifict cell.
At #06 row code, We found an exception, it seems that into custom column, something is not istantiated.......
01.[...]02.Dim _CodiceArticoloColumn As GridViewTextButtonColumn = .AddTextButtonColumn("CodiceArticoloColumn", "Articolo", "CodiceArticolo", True, Drawing.ContentAlignment.MiddleLeft)03.AddHandler _CodiceArticoloColumn.Click, AddressOf _CodiceArticoloColumn_Click04.[...]05. 06.Public Function AddTextButtonColumn(p_Name As String, p_Caption As String, p_FieldName As String, p_Editable As Boolean, p_TextAlignment As Drawing.ContentAlignment) As GridViewTextButtonColumn07. 08. Dim _Column As New GridViewTextButtonColumn(p_Name)09. 10. _Column.FieldName = p_FieldName11. _Column.HeaderText = p_Caption12. _Column.ReadOnly = Not p_Editable13. _Column.TextAlignment = p_TextAlignment14. _Column.HeaderTextAlignment = p_TextAlignment15. 16. _Column.HeaderTextAlignment = ContentAlignment.BottomLeft17. _Column.WrapText = True18. '_Column.Multiline = True19. _Column.Width = 520. 21. RowsRadGridView.MasterTemplate.Columns.Add(_Column)22. 23. Return _Column24. 25.End Function
01.For Each _RigaProforma In _Rows02. 03. Dim _RowInfo = RowsEditableGridView.AddRow04. 05. _RowInfo.Cells("NumeroRigaColumn").Value = _RigaProforma.NumeroRiga06. _RowInfo.Cells("CodiceArticoloColumn").Value = _RigaProforma.CodiceArticolo07. _RowInfo.Cells("CodiceEsternoColumn").Value = _RigaProforma.CodiceEsterno08. _RowInfo.Cells("DescrizioneColumn").Value = _RigaProforma.Descrizione09. 10. If _RigaProforma.CodiceArticolo <> "" Then11. _RowInfo.Cells("DescrizioneModelloColumn").Value = _RigaProforma.DatiArticolo.Caratteristiche12. Else13. _RowInfo.Cells("DescrizioneModelloColumn").Value = _RigaProforma.Descrizione14. End If15. 16. If _RigaProforma.Quantità <> 0 Or17. _RigaProforma.PrezzoUnitario <> 0 Then18. _RowInfo.Cells("UMColumn").Value = _RigaProforma.CodiceUnità Misura19. _RowInfo.Cells("QuantitaColumn").Value = _RigaProforma.Quantità 20. _RowInfo.Cells("PrezzoUnitarioColumn").Value = _RigaProforma.PrezzoUnitario21. _RowInfo.Cells("ScontoListinoColumn").Value = _RigaProforma.Sconto122. _RowInfo.Cells("ScontoClienteColumn").Value = _RigaProforma.Sconto223. _RowInfo.Cells("TensioneColumn").Value = _RigaProforma.Tensione24. _RowInfo.Cells("PotenzaColumn").Value = _RigaProforma.Potenza25. 26. End If27. 28. NextERRATA CORRIDGE:
"At #06 row code " refers to seconds portion of code, sorry...
BINGO!
I changed a costructor, I need to use approach (unbound) by Cells("").Value, then I need to have uniqueName and fieldName.
Thank you.
01.Public Class GridViewTextButtonColumn02. Inherits GridViewDataColumn03. 04.Public Sub New(ByVal uniqueName As String, ByVal fieldName As String)05. MyBase.New(uniqueName, fieldName)06. 07.End Sub08. 09.[...]You can handle the click event directly in the custom cell class. Please note that you can easily access the grid inside the event handler:
Protected Overrides Sub CreateChildElements() MyBase.CreateChildElements() button = New RadButtonElement() button.Text = "..." button.StretchHorizontally = False button.StretchVertically = False AddHandler button.Click, AddressOf Button_Click Me.Children.Add(button)End SubPrivate Sub Button_Click(ByVal sender As Object, ByVal e As EventArgs) Dim grid = Me.GridControlEnd SubI hope this will be useful. Let me know if you have additional questions.
Regards,
Dimitar
Telerik by Progress
Ok it's works.
Finally I adopted first way (by editor). :-)
Now I have a question, after I setted value in editor, how can I pass it to cell element?
Actually I modify the value (Text), I see it, but when exit from editor, it refresh value to original one.
I created this custom control, but when I edit a cell, not appears value, why?
01.Public Class TextButtonEditor02. Inherits RadTextBoxEditor03. 04. Dim _Editor As EditorButtonEditorElement05. 06. Protected Overrides Function CreateEditorElement() As RadElement07. Return New EditorButtonEditorElement08. End Function09. 10. Public Overrides Property Value() As Object11. Get12. Dim editor As EditorButtonEditorElement = CType(Me.EditorElement, EditorButtonEditorElement)13. Return editor.Text14. End Get15. Set(ByVal value As Object)16. Dim editor As EditorButtonEditorElement = CType(Me.EditorElement, EditorButtonEditorElement)17. If value IsNot Nothing AndAlso value IsNot DBNull.Value Then18. editor.Text = CStr(value)19. Else20. editor.Text = ""21. End If22. End Set23. End Property24. Public Overrides Sub BeginEdit()25. MyBase.BeginEdit()26. Me.EditorElement.Focus()27. AddHandler(CType(EditorElement, EditorButtonEditorElement)).TextChanged, AddressOf TextButtonEditor_TextChanged28. End Sub29. Public Overrides Function EndEdit() As Boolean30. RemoveHandler(CType(EditorElement, EditorButtonEditorElement)).TextChanged, AddressOf TextButtonEditor_TextChanged31. Return MyBase.EndEdit()32. End Function33. Private Sub TextButtonEditor_TextChanged(ByVal sender As Object, ByVal e As EventArgs)34. OnValueChanged()35. End Sub36.End Class37. 38.Public Class EditorButtonEditorElement39. Inherits RadTextBoxEditorElement40. 41. Dim _TextBox As RadTextBoxItem42. Dim _Column As GridViewColumn43. 44. Public Sub New()45. 46. Dim _Button As New RadButtonElement47. 48. AddHandler _Button.Click, AddressOf _Button_Click49. 50. _Button.Padding = New Windows.Forms.Padding(2, 0, 2, -2)51. _Button.Margin = New Windows.Forms.Padding(0, 0, 0, 0)52. _Button.Text = "..."53. 54. _TextBox = New RadTextBoxItem55. 56. Me.Children.Clear()57. 58. Dim _DockLayoutPanel As New DockLayoutPanel59. _DockLayoutPanel.Children.Add(_Button)60. _DockLayoutPanel.Children.Add(_TextBox)61. 62. DockLayoutPanel.SetDock(_TextBox, Dock.Left)63. DockLayoutPanel.SetDock(_Button, Dock.Right)64. 65. Children.Add(_DockLayoutPanel)66. 67. End Sub68. 69. Public Event TextValueChanged As EventHandler70. 71. Protected Overrides Function MeasureOverride(ByVal availableSize As System.Drawing.SizeF) As System.Drawing.SizeF72. Dim desiredHeight As Integer = 3073. For Each element As RadElement In Me.Children74. element.Measure(New System.Drawing.SizeF(availableSize.Width, desiredHeight))75. Next element76. Return New System.Drawing.SizeF(1, desiredHeight)77. End Function78. 79. Protected Overrides Sub OnPropertyChanged(ByVal e As RadPropertyChangedEventArgs)80. MyBase.OnPropertyChanged(e)81. If e.Property Is RadTextBoxItem.TextProperty AndAlso Me.Parent IsNot Nothing Then82. 'e.Property = _TextBox.Text83. '_TextBox.Text = CStr(e.NewValue)84. RaiseEvent TextValueChanged(Me, EventArgs.Empty)85. End If86. End Sub87. 88. Public Event ButtonClick(sender As Object, column As GridViewColumn, e As EventArgs, ByRef value As String)89. 90. Private Sub _Button_Click(sender As Object, e As EventArgs)91. RaiseEvent ButtonClick(Me, _Column, e, _TextBox.Text)92. End Sub93. 94. Public Sub SetName(column As GridViewColumn)95. _Column = column96. End Sub97.End ClassYou can set the cell value as well:
Private Sub button_Click(ByVal sender As Object, ByVal e As EventArgs) Dim cell = TryCast(Me.Parent, GridDataCellElement) cell.Value = "test"End SubLet me know how this works on your side.
Regards,
Dimitar
Telerik by Progress
This works fine on my side. I have attached my test project. Could you please check it and let me know how it differs from your real setup?
Thank you in advance for your patience and cooperation.
Regards,
Dimitar
Telerik by Progress
ok, it works now.
I didn't create GridViewButtonCell class...
Thank you.
Hello,
How can I prevent users from typing into cell when a custom editor is used? Events like KeyDown will not fire when cell is in edit mode. I only want to allow them to change values from the form displayed once button editor is clicked.
Wojciech
You should use the events or the properties of the editor, not the grid. For example, you can use the CellEditorInitialized event to access the editor and make it read-only:
private void RadGridView1_CellEditorInitialized(object sender, GridViewCellEventArgs e){ RadTextBoxEditor editor = e.ActiveEditor as RadTextBoxEditor; if (editor != null && e.Column.Name == "Name") { var element = editor.EditorElement as RadTextBoxEditorElement; element.TextBoxItem.ReadOnly = true; }}Should you have any other questions do not hesitate to ask.
Regards,
Dimitar
Progress Telerik
Thank you for reply. It works as expected now.
Wojciech
I used the custom cell solution to show a button in the cell. Its base class is GridViewTextBoxColumn, and its default editor type's base class is GridDataCellElement. When I add the column, the Header Text disappears and turns white. But if I switch it back to GridViewTextBoxColumn, the header text displays just fine. I've combed over the link article, and can't find where I'm not doing anything differently.
Any thoughts?
Vania
Hi Vania,
Without checking the code I cannot say what is causing this effect. Would it be possible to share the code? Perhaps it would be even better if you could open a new support ticket and atched your project there.
Thank you in advance for your patience and cooperation.
Regards,
Dimitar
Progress Telerik
