This is a migrated thread and some comments may be shown as answers.

Filter on custom column bound to custom type

5 Answers 100 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Andrea
Top achievements
Rank 1
Andrea asked on 04 Nov 2016, 11:09 AM

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

Sort by
0
Dimitar
Telerik team
answered on 04 Nov 2016, 12:39 PM
Hello Andrea,

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
Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
0
Andrea
Top achievements
Rank 1
answered on 07 Nov 2016, 03:41 PM

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.

0
Dimitar
Telerik team
answered on 08 Nov 2016, 08:45 AM
Hello Andrea,

Have you tested all the filters when this drop down is created like this? Are they working properly?

Regards,
Dimitar
Telerik by Progress
Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
0
Andrea
Top achievements
Rank 1
answered on 08 Nov 2016, 09:34 AM

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

0
Dimitar
Telerik team
answered on 08 Nov 2016, 10:34 AM
Hi 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. 
 
Regards,
Dimitar
Telerik by Progress
Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
Tags
GridView
Asked by
Andrea
Top achievements
Rank 1
Answers by
Dimitar
Telerik team
Andrea
Top achievements
Rank 1
Share this question
or