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
TextButtonCellElement
02.
Inherits
GridDataCellElement
03.
04.
Public
Sub
New
(
ByVal
column
As
GridViewColumn,
ByVal
row
As
GridRowElement)
05.
MyBase
.
New
(column, row)
06.
End
Sub
07.
08.
Private
_RadTextBoxControl
As
RadTextBoxElement
09.
Private
_RadButtonElement
As
RadButtonElement
10.
11.
Protected
Overrides
Sub
CreateChildElements()
12.
MyBase
.CreateChildElements()
13.
14.
_RadTextBoxControl =
New
RadTextBoxElement()
15.
Me
.Children.Add(_RadTextBoxControl)
16.
17.
_RadButtonElement =
New
RadButtonElement
18.
_RadButtonElement.Text =
"..."
19.
_RadButtonElement.Margin =
New
Windows.Forms.Padding(0, 1, 3, 1)
20.
AddHandler
_RadButtonElement.Click,
AddressOf
_RadButtonElement_Click
21.
Me
.Children.Add(_RadButtonElement)
22.
23.
End
Sub
24.
25.
Protected
Overrides
Sub
DisposeManagedResources()
26.
RemoveHandler
_RadButtonElement.Click,
AddressOf
_RadButtonElement_Click
27.
MyBase
.DisposeManagedResources()
28.
End
Sub
29.
30.
Protected
Overrides
Function
ArrangeOverride(
ByVal
finalSize
As
SizeF)
As
SizeF
31.
If
Me
.Children.Count = 2
Then
32.
Dim
progressBarWidth
As
Single
= finalSize.Width - _RadButtonElement.DesiredSize.Width
33.
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
If
38.
Return
finalSize
39.
End
Function
40.
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
Sub
45.
46.
Protected
Overrides
Sub
SetContentCore(
ByVal
value
As
Object
)
47.
If
Me
.Value IsNot
Nothing
AndAlso
Me
.Value IsNot DBNull.Value
Then
48.
Me
._RadTextBoxControl.Text =
CStr
(
Me
.Value)
49.
End
If
50.
End
Sub
51.
52.
Protected
Overrides
ReadOnly
Property
ThemeEffectiveType()
As
Type
53.
Get
54.
Return
GetType
(GridDataCellElement)
55.
End
Get
56.
End
Property
57.
58.
Public
Overrides
Function
IsCompatible(
ByVal
data
As
GridViewColumn,
ByVal
context
As
Object
)
As
Boolean
59.
Return
TypeOf
data
Is
GridViewTextButtonColumn
AndAlso
TypeOf
context
Is
GridDataRowElement
60.
End
Function
61.
62.
End
Class
63.
64.
Public
Class
GridViewTextButtonColumn
65.
Inherits
GridViewDataColumn
66.
Public
Sub
New
(
ByVal
fieldName
As
String
)
67.
MyBase
.
New
(fieldName)
68.
69.
End
Sub
70.
71.
Private
_GridViewRowInfo
As
GridViewRowInfo
72.
Public
Property
GridViewRowInfo()
As
GridViewRowInfo
73.
Get
74.
Return
_GridViewRowInfo
75.
End
Get
76.
Set
(
ByVal
value
As
GridViewRowInfo)
77.
_GridViewRowInfo = value
78.
End
Set
79.
End
Property
80.
81.
Public
Sub
Click(sender
As
Object
, e
As
EventArgs)
82.
Throw
New
NotImplementedException()
83.
End
Sub
84.
85.
Public
Overrides
Function
GetCellType(
ByVal
row
As
GridViewRowInfo)
As
Type
86.
87.
If
TypeOf
row
Is
GridViewDataRowInfo
Then
88.
Return
GetType
(TextButtonCellElement)
89.
End
If
90.
Return
MyBase
.GetCellType(row)
91.
92.
_GridViewRowInfo = row
93.
End
Function
94.
End
Class
Strange, 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_Click
04.
[...]
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
GridViewTextButtonColumn
07.
08.
Dim
_Column
As
New
GridViewTextButtonColumn(p_Name)
09.
10.
_Column.FieldName = p_FieldName
11.
_Column.HeaderText = p_Caption
12.
_Column.
ReadOnly
=
Not
p_Editable
13.
_Column.TextAlignment = p_TextAlignment
14.
_Column.HeaderTextAlignment = p_TextAlignment
15.
16.
_Column.HeaderTextAlignment = ContentAlignment.BottomLeft
17.
_Column.WrapText =
True
18.
'_Column.Multiline = True
19.
_Column.Width = 5
20.
21.
RowsRadGridView.MasterTemplate.Columns.Add(_Column)
22.
23.
Return
_Column
24.
25.
End
Function
01.
For
Each
_RigaProforma
In
_Rows
02.
03.
Dim
_RowInfo = RowsEditableGridView.AddRow
04.
05.
_RowInfo.Cells(
"NumeroRigaColumn"
).Value = _RigaProforma.NumeroRiga
06.
_RowInfo.Cells(
"CodiceArticoloColumn"
).Value = _RigaProforma.CodiceArticolo
07.
_RowInfo.Cells(
"CodiceEsternoColumn"
).Value = _RigaProforma.CodiceEsterno
08.
_RowInfo.Cells(
"DescrizioneColumn"
).Value = _RigaProforma.Descrizione
09.
10.
If
_RigaProforma.CodiceArticolo <>
""
Then
11.
_RowInfo.Cells(
"DescrizioneModelloColumn"
).Value = _RigaProforma.DatiArticolo.Caratteristiche
12.
Else
13.
_RowInfo.Cells(
"DescrizioneModelloColumn"
).Value = _RigaProforma.Descrizione
14.
End
If
15.
16.
If
_RigaProforma.Quantità <> 0
Or
17.
_RigaProforma.PrezzoUnitario <> 0
Then
18.
_RowInfo.Cells(
"UMColumn"
).Value = _RigaProforma.CodiceUnità Misura
19.
_RowInfo.Cells(
"QuantitaColumn"
).Value = _RigaProforma.QuantitÃ
20.
_RowInfo.Cells(
"PrezzoUnitarioColumn"
).Value = _RigaProforma.PrezzoUnitario
21.
_RowInfo.Cells(
"ScontoListinoColumn"
).Value = _RigaProforma.Sconto1
22.
_RowInfo.Cells(
"ScontoClienteColumn"
).Value = _RigaProforma.Sconto2
23.
_RowInfo.Cells(
"TensioneColumn"
).Value = _RigaProforma.Tensione
24.
_RowInfo.Cells(
"PotenzaColumn"
).Value = _RigaProforma.Potenza
25.
26.
End
If
27.
28.
Next
ERRATA 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
GridViewTextButtonColumn
02.
Inherits
GridViewDataColumn
03.
04.
Public
Sub
New
(
ByVal
uniqueName
As
String
,
ByVal
fieldName
As
String
)
05.
MyBase
.
New
(uniqueName, fieldName)
06.
07.
End
Sub
08.
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
Sub
Private
Sub
Button_Click(
ByVal
sender
As
Object
,
ByVal
e
As
EventArgs)
Dim
grid =
Me
.GridControl
End
Sub
I 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
TextButtonEditor
02.
Inherits
RadTextBoxEditor
03.
04.
Dim
_Editor
As
EditorButtonEditorElement
05.
06.
Protected
Overrides
Function
CreateEditorElement()
As
RadElement
07.
Return
New
EditorButtonEditorElement
08.
End
Function
09.
10.
Public
Overrides
Property
Value()
As
Object
11.
Get
12.
Dim
editor
As
EditorButtonEditorElement =
CType
(
Me
.EditorElement, EditorButtonEditorElement)
13.
Return
editor.Text
14.
End
Get
15.
Set
(
ByVal
value
As
Object
)
16.
Dim
editor
As
EditorButtonEditorElement =
CType
(
Me
.EditorElement, EditorButtonEditorElement)
17.
If
value IsNot
Nothing
AndAlso
value IsNot DBNull.Value
Then
18.
editor.Text =
CStr
(value)
19.
Else
20.
editor.Text =
""
21.
End
If
22.
End
Set
23.
End
Property
24.
Public
Overrides
Sub
BeginEdit()
25.
MyBase
.BeginEdit()
26.
Me
.EditorElement.Focus()
27.
AddHandler
(
CType
(EditorElement, EditorButtonEditorElement)).TextChanged,
AddressOf
TextButtonEditor_TextChanged
28.
End
Sub
29.
Public
Overrides
Function
EndEdit()
As
Boolean
30.
RemoveHandler
(
CType
(EditorElement, EditorButtonEditorElement)).TextChanged,
AddressOf
TextButtonEditor_TextChanged
31.
Return
MyBase
.EndEdit()
32.
End
Function
33.
Private
Sub
TextButtonEditor_TextChanged(
ByVal
sender
As
Object
,
ByVal
e
As
EventArgs)
34.
OnValueChanged()
35.
End
Sub
36.
End
Class
37.
38.
Public
Class
EditorButtonEditorElement
39.
Inherits
RadTextBoxEditorElement
40.
41.
Dim
_TextBox
As
RadTextBoxItem
42.
Dim
_Column
As
GridViewColumn
43.
44.
Public
Sub
New
()
45.
46.
Dim
_Button
As
New
RadButtonElement
47.
48.
AddHandler
_Button.Click,
AddressOf
_Button_Click
49.
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
RadTextBoxItem
55.
56.
Me
.Children.Clear()
57.
58.
Dim
_DockLayoutPanel
As
New
DockLayoutPanel
59.
_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
Sub
68.
69.
Public
Event
TextValueChanged
As
EventHandler
70.
71.
Protected
Overrides
Function
MeasureOverride(
ByVal
availableSize
As
System.Drawing.SizeF)
As
System.Drawing.SizeF
72.
Dim
desiredHeight
As
Integer
= 30
73.
For
Each
element
As
RadElement
In
Me
.Children
74.
element.Measure(
New
System.Drawing.SizeF(availableSize.Width, desiredHeight))
75.
Next
element
76.
Return
New
System.Drawing.SizeF(1, desiredHeight)
77.
End
Function
78.
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
Then
82.
'e.Property = _TextBox.Text
83.
'_TextBox.Text = CStr(e.NewValue)
84.
RaiseEvent
TextValueChanged(
Me
, EventArgs.Empty)
85.
End
If
86.
End
Sub
87.
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
Sub
93.
94.
Public
Sub
SetName(column
As
GridViewColumn)
95.
_Column = column
96.
End
Sub
97.
End
Class
You 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
Sub
Let 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