Hello, I have a custom column, that is bound to a custom type, the custom type is a complex type, that have a (public string Display) property, that is the one I wish to use to filter the grid.
The excel like filter is working, maybe because the compex type have a "tostring" method, i attach a screenshot of the grid.
The standard filter is not working instead. All the filters are disabled. How can I make the filter cell to work with the complex type? I think i have to create a new filter cell descending from Telerik.WinControls.UI.GridFilterCellElement
then on my custom column:
public
override
Type GetCellType(GridViewRowInfo row)
{
if
(row
is
GridViewDataRowInfo)
{
return
typeof
(LookupGridColumnElement);
}
else
if
(row
is
Telerik.WinControls.UI.GridViewFilteringRowInfo)
{
return
typeof
(LookupGridColumnFilterElement);
}
return
base
.GetCellType(row);
}
Is that the correct way? What do i need to override on my filter cell to let it work as if it were bound to a string field?
5 Answers, 1 is accepted
You only need to set the FieldName in this case. Here is a complete example for this:
public
partial
class
Form1 : Form
{
public
Form1()
{
InitializeComponent();
radGridView1.EnableFiltering =
true
;
BindingList<Data> data =
new
BindingList<Data>();
for
(
int
i = 0; i < 10; i++)
{
var type =
new
CustomType() { Name =
"Name"
+ i };
var obj =
new
Data() { Text =
"Row "
+ i, Type = type };
data.Add(obj);
}
radGridView1.DataSource = data;
}
protected
override
void
OnLoad(EventArgs e)
{
base
.OnLoad(e);
radGridView1.Columns[1].FieldName =
"Type.Name"
;
}
}
class
Data
{
public
string
Text {
get
;
set
; }
public
CustomType Type {
get
;
set
; }
}
class
CustomType
{
public
string
Name {
get
;
set
; }
public
override
string
ToString()
{
return
Name;
}
}
I hope this will be useful. Let me know if you have additional questions.
Regards,
Dimitar
Telerik by Progress
Hi, unfortunately i need to keep the field point to a structure that holds 2 values, one is the display value for the field, the other is the ID of this object on a GIS database holding million records, so i can't use a combobox, I am using a custom column and a custom editor, and this editor have to edit all fields on the complex property.
Anyway i finally managed how to resolve.
My custom column override the getCellType
public
override
Type GetCellType(GridViewRowInfo row)
{
if
(row
is
GridViewDataRowInfo)
{
return
typeof
(LookupGridColumnElement);
}
else
if
(row
is
Telerik.WinControls.UI.GridViewFilteringRowInfo)
{
return
typeof
(LookupGridColumnFilterElement);
}
return
base
.GetCellType(row);
}
the custom filter cell overrides the CreateFilterMenu, returning the same kind of operators as the string
protected
override
RadDropDownMenu CreateFilterMenu(Type dataType)
{
return
base
.CreateFilterMenu(
typeof
(
string
));
}
I need to intercept the OnEditorRequired on the grid
protected
override
void
OnEditorRequired(
object
sender, EditorRequiredEventArgs e)
{
if
(sender
is
GridViewEditManager)
{
var gm = sender
as
GridViewEditManager;
if
(gm.GridViewElement.CurrentRow
is
Telerik.WinControls.UI.GridViewFilteringRowInfo
&& gm.GridViewElement.CurrentColumn
is
LookupGridColumn)
{
e.EditorType =
typeof
(LookupFilterEditor);
}
}
base
.OnEditorRequired(sender, e);
}
and finally the editor for the filter cell override the standard textbox editor but override the value method
public
class
LookupFilterEditor : RadTextBoxEditor
{
public
override
object
Value
{
get
{
return
new
Sysimex.Database.LookupField(0,
base
.Value);
}
set
{
Sysimex.Database.LookupField Value = value
as
Sysimex.Database.LookupField;
base
.Value = Value?.Display;
}
}
}
I know it may look overcomplicated but the editor i am using to lookup the external millions row key is quite good and this way i can reuse it.
Have you tested all the filters when this drop down is created like this? Are they working properly?
Regards,
Dimitar
Telerik by Progress
Hi Dimitar, I am also using a custom comparer on the grid, that support all the filter operators for this kind of field too.
public class RecordBaseComparer<T> : IComparer<GridViewRowInfo> wereh T : class, IRecordBase
that when the filter descriptors set change will rebuild an internal set of predicates using a switch statement that handle all possible elements on the Telerik.WinControls.Data.FilterOperator enum, if the field object have a comparer, that is my case.
switch
(fd.Operator)
{
case
Telerik.WinControls.Data.FilterOperator.Contains:
case
Telerik.WinControls.Data.FilterOperator.IsLike:
predicate = (x, y) =>
(x?.ToString() ??
""
).IndexOf(y?.ToString() ??
""
, StringComparison.OrdinalIgnoreCase) >= 0;
break
;
case
Telerik.WinControls.Data.FilterOperator.IsNotLike:
case
Telerik.WinControls.Data.FilterOperator.NotContains:
predicate = (x, y) =>
(x?.ToString() ??
""
).IndexOf(y?.ToString() ??
""
, StringComparison.OrdinalIgnoreCase) < 0;
break
;
case
Telerik.WinControls.Data.FilterOperator.EndsWith:
predicate = (x, y) =>
(x?.ToString() ??
""
).EndsWith(y?.ToString() ??
""
, StringComparison.OrdinalIgnoreCase);
break
;
case
Telerik.WinControls.Data.FilterOperator.IsEqualTo:
predicate = (x, y) => Object.Equals(x, y);
break
;
case
Telerik.WinControls.Data.FilterOperator.IsGreaterThan:
predicate = (x, y) => comparer(x, y) > 0;
break
;
case
Telerik.WinControls.Data.FilterOperator.IsGreaterThanOrEqualTo:
predicate = (x, y) => comparer(x, y) >= 0;
break
;
case
Telerik.WinControls.Data.FilterOperator.IsLessThan:
predicate = (x, y) => comparer(x, y) < 0;
break
;
case
Telerik.WinControls.Data.FilterOperator.IsLessThanOrEqualTo:
predicate = (x, y) => comparer(x, y) <= 0;
break
;
case
Telerik.WinControls.Data.FilterOperator.IsNotEqualTo:
predicate = (x, y) => comparer(x, y) != 0;
break
;
case
Telerik.WinControls.Data.FilterOperator.IsNotNull:
predicate = (x, y) => comparer(x,
null
) != 0;
break
;
case
Telerik.WinControls.Data.FilterOperator.IsNull:
predicate = (x, y) => comparer(x,
null
) == 0;
break
;
case
Telerik.WinControls.Data.FilterOperator.StartsWith:
predicate = (x, y) =>
(x?.ToString() ??
""
).StartsWith(y?.ToString() ??
""
, StringComparison.OrdinalIgnoreCase);
break
;
case
Telerik.WinControls.Data.FilterOperator.None:
case
Telerik.WinControls.Data.FilterOperator.IsContainedIn:
case
Telerik.WinControls.Data.FilterOperator.IsNotContainedIn:
default
:
throw
new
NotSupportedException(
"Filter not supported"
);
}
I have to say that your winforms controls are really good when some customization is needed.
Best Regards
Andrea
I am glad that you have implemented the desired functionality. Thanks for sharing your solution with the community as well.
Please do not hesitate to contact us with any additional questions or concerns.
Dimitar
Telerik by Progress