Filter on custom column bound to custom type

6 posts, 0 answers
  1. Andrea
    Andrea avatar
    52 posts
    Member since:
    Oct 2012

    Posted 04 Nov Link to this post

    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?

     

     

  2. Dimitar
    Admin
    Dimitar avatar
    1415 posts

    Posted 04 Nov Link to this post

    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.
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Andrea
    Andrea avatar
    52 posts
    Member since:
    Oct 2012

    Posted 07 Nov in reply to Dimitar Link to this post

    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.

  5. Dimitar
    Admin
    Dimitar avatar
    1415 posts

    Posted 08 Nov Link to this post

    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.
  6. Andrea
    Andrea avatar
    52 posts
    Member since:
    Oct 2012

    Posted 08 Nov in reply to Dimitar Link to this post

    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

  7. Dimitar
    Admin
    Dimitar avatar
    1415 posts

    Posted 08 Nov Link to this post

    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.
Back to Top
UI for WinForms is Visual Studio 2017 Ready