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

ColumnFilterDescriptor changed

7 Answers 432 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Luc
Top achievements
Rank 1
Luc asked on 04 Jun 2012, 12:34 PM
since braking changed on for the Q1-2012 version your ColumnFilterDescriptor is not internal and was public..   :( 
I use to inherits this class for a special feature for filtering a "flagable enum"

Since it is cannot be inherits anymore, I try ro create my filter again

big lines:
1. standard "disctinct values"
2. an enum that have multiple state are included in filter even if the values is not "EQUALS" but contains...


My problem reside on the "yellow hilighted line."

Braking changes links : http://www.telerik.com/community/forums/wpf/gridview/known-issues-and-breaking-changes---radgridview.aspx
complete doc : Doc

My code: (not original, but cleaned for reading perpose..)

class MaxEnumFlagsDescriptor : FilterDescriptor

{

    private FilterDescriptor<MaintenanceBoxDataDataTableRow> Filter;

    private string dataMember;

    /// <summary>

    /// Initializes a new instance of the <see cref="MaxEnumFlagsDescriptor"/> class.

    /// </summary>

    /// <param name="control">The column.</param>

    /// <param name="dataMember">The data member.</param>

    /// <param name="enumType">Type of the enum.</param>

    public MaxEnumFlagsDescriptor(MaxFilteringControl control, string dataMember, Type enumType)

    {

        if (dataMember.StartsWith("["))

            dataMember = dataMember.RemoveFromStart(1).RemoveFromEnd(1);

        this.Control = control;

        this.Column = control.GridColumn as GridViewBoundColumnBase;

        this.dataMember = dataMember;

        this.EnumType = enumType;

        Filter = new FilterDescriptor<MaintenanceBoxDataDataTableRow>();

        Filter.FilteringExpression = (e) => (Check(e));

    }

     /// <summary>

    /// Creates the filter expression.

    /// </summary>

    /// <param name="instance">The instance.</param>

    /// <returns></returns>

    public override System.Linq.Expressions.Expression CreateFilterExpression(System.Linq.Expressions.Expression instance)

    {

        return Filter.CreateFilterExpression(instance);

    }

     private bool Check(DataRow row)

    {

        if (this.DistinctValue == null || !this.Control.IsActive)

            return true;

        var desc = this.DistinctValue;  // this was available in the ColumnFilterDescriptor. originaly
                                        // in the class (so how to get it..)
                                        // HOW TO GET THE CHECKED VALUES OF THE DISTINCT VALUE LIST

        if (!desc.Any())

            return true;

        Debug.Assert(row != null, "Should have found a Row");

        if (row != null)

        {

            var inf = row[this.dataMember];

            if (inf == DBNull.Value)

                inf = null;

            if (inf == null)

                return desc.Any(c => c == null);

            else

            {

                var enumType = this.EnumType;

                try

                {

                    var val = Enum.ToObject(enumType, inf).ToString();

                    return desc.Any(c => IsInclude(c, val, enumType));

                }

                catch (System.Exception ex)

                {

                    // In case of old value

                    Debug.Fail(ex.Message);

                    return false;

                }

            }

        }

        return true;

    }

    private static bool IsInclude(object value, string data, Type enumType)

    {

        var val = Enum.ToObject(enumType, value).ToString();

        return data.IndexOf(val) >= 0;

    }

}


7 Answers, 1 is accepted

Sort by
0
Rossen Hristov
Telerik team
answered on 04 Jun 2012, 12:55 PM
Hello,

We are not really sure what do you mean by this.

The ColumnFilterDescriptor class NEVER had a property called DistinctValue in its entire history, so we can't understand where did you see this property. There was never such a property.

We see that you are building some kind of a custom filtering control, so we are not really sure what is going on inside it.

How were you inheriting from the ColumnFilterDescriptor class? Your source code shows nothing like this. In your source code you inherit from FilterDescriptor and not from ColumnFilterDescriptor.

The yellow line: this.DistinctValue does not exist because it does not exist -- it is your class and it does not have such a property. That is why it does not exist.

We are totally perplexed.

Please, try to explain in a well structured manner what are you trying to achieve and what your problems are, since the information you have provided is totally misleading.

Kind reards
Ross
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Rossen Hristov
Telerik team
answered on 04 Jun 2012, 01:10 PM
Hi,

In case you are asking how to obtain the distinct values of an IColumnFilterDescriptor (the public interface that you have access to) you can get them like this:

IEnumerable<object> distinctValues = myColumn.ColumnFilterDescriptor.DistinctFilter.DistinctValues;

Maybe this is what you are looking for?

Here is the source code of the public interfaces for your reference:

/// <summary>
/// Represents a column filter descriptor associated with a specific column.
/// </summary>
public interface IColumnFilterDescriptor : IFilterDescriptor, ISuspendNotifications
{
    /// <summary>
    /// Gets the distinct filter for the column. This represents the upper part of the filtering UI.
    /// </summary>
    /// <value>Gets the distinct filter for the column.</value>
    IDistinctValuesFilterDescriptor DistinctFilter { get; }
 
    /// <summary>
    /// Gets the field filter for the column. This represents the lower part of the filtering UI.
    /// </summary>
    /// <value>The field filter for the column.</value>
    IFieldFilterDescriptor FieldFilter { get; }
 
    /// <summary>
    /// Gets a value indicating, which indicates that this filter can be applied.
    /// </summary>
    /// <value><c>true</c> if this instance filter is applied; otherwise, <c>false</c>.</value>
    bool IsActive { get; }
 
    /// <summary>
    /// Gets the corresponding column for this filter descriptor.
    /// </summary>
    /// <value>The column.</value>
    GridViewColumn Column { get; }
 
    /// <summary>
    /// Clears this column filter descriptor and deactivates it.
    /// </summary>
    void Clear();
 
    /// <summary>
    /// Refreshes the column filter descriptor from its parent column.
    /// </summary>
    void Refresh();
}

 

/// <summary>
    /// Represents the distinct filter descriptor of a column filter descriptor.
    /// </summary>
    public interface IDistinctValuesFilterDescriptor : IFilterDescriptor
    {
        /// <summary>
        /// Gets the distinct values.
        /// </summary>
        /// <value>The distinct values.</value>
        IEnumerable<object> DistinctValues { get; }
 
        /// <summary>
        /// Gets the filter descriptors.
        /// </summary>
        /// <value>The filter descriptors.</value>
        IEnumerable<OperatorValueFilterDescriptorBase> FilterDescriptors { get; }
 
        /// <summary>
        /// Tries to find descriptor.
        /// </summary>
        /// <param name="distinctValue">The distinct value.</param>
        /// <returns></returns>
        OperatorValueFilterDescriptorBase TryFindDescriptor(object distinctValue);
         
        /// <summary>
        /// Adds the distinct value.
        /// </summary>
        /// <param name="distinctValue">The distinct value.</param>
        void AddDistinctValue(object distinctValue);
 
        /// <summary>
        /// Removes the distinct value.
        /// </summary>
        /// <param name="distinctValue">The distinct value.</param>
        /// <returns>True if the distinct value was removed. Otherwise false.</returns>
        bool RemoveDistinctValue(object distinctValue);
         
        /// <summary>
        /// Clears the descriptors;
        /// </summary>
        void Clear();
 
        /// <summary>
        /// Gets a value indicating whether this filter is active.
        /// </summary>
        /// <value><c>true</c> if the filter is active; otherwise, <c>false</c>.</value>
        bool IsActive { get; }
    }

Regards,

Ross
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Luc
Top achievements
Rank 1
answered on 04 Jun 2012, 02:32 PM
Sorry for the misunderstod DistinctValue was in fact in my FilterControl implementation... and override the Prepare méthode to set add in the gridControl.FilterDescriptors collection

I will try your myColumn.ColumnFilterDescriptor.DistinctFilter.DistinctValues;  hint
thanks
0
Luc
Top achievements
Rank 1
answered on 04 Jun 2012, 03:45 PM
Just to make sure I get it right!!!
1. I create a Filtering control base on your FilteringControl (to get the discinct values control selector)
2. Override Prepare to "adjust the FilterDescriptors collection of the grid control

When I select a item is the "distinct value selector" no rows visisible
I did place a Break point to check if desc.Any()  (second part of code block)

Does the clear filter/add filter is ok  in method "CreateEnumFlagFilters" ?

Any hint ?

 

internal class MaxFilteringControl : FilteringControl
   {
       /// <summary>
       /// Initializes a new instance of the <see cref="MaxFilteringControl"/> class.
       /// </summary>
       /// <param name="column">The column.</param>
       public MaxFilteringControl(ColumnDefinition column)  // my colum defintion
       {
           this.Column = column;
       }
 
 
       /// <summary>
       /// Prepares the component for the column it will service.
       /// </summary>
       /// <param name="column">The column to prepare for.</param>
       public override void Prepare(Telerik.Windows.Controls.GridViewColumn column)
       {
           if (this.Column != null && TypeUtility.IsEnumFlags(this.Column.ColumnType)) // if the enum is Flagable
               CreateEnumFlagFilters(column);
 
           base.Prepare(column);
       }
 
 
       internal void CreateEnumFlagFilters(Telerik.Windows.Controls.GridViewColumn gridColumn)
       {
           var colbase = gridColumn as GridViewBoundColumnBase;
           Debug.Assert(colbase != null, "column is not a GridViewBoundColumnBase");
           if (colbase != null)
           {
               string path = colbase.DataMemberBinding.Path.Path;
 
               // my filter descriptor
               MaxEnumFlagsDescriptor fil = new MaxEnumFlagsDescriptor(colbase, path, this.Column.ColumnType);
               gridColumn.ClearFilters();
               gridColumn.DataControl.FilterDescriptors.Add(fil);
 
           }
       }
   }

 

/// <summary>
/// Initializes a new instance of the <see cref="MaxEnumFlagsDescriptor"/> class.
/// </summary>
/// <param name="column">The column.</param>
/// <param name="dataMember">The data member.</param>
/// <param name="enumType">Type of the enum.</param>
public MaxEnumFlagsDescriptor(GridViewBoundColumnBase column, string dataMember, Type enumType)
{
    if (dataMember.StartsWith("["))
        dataMember = dataMember.RemoveFromStart(1).RemoveFromEnd(1);
 
    this.Column = column;
    this.DataMember = dataMember;
    this.EnumType = enumType;
    this.Filter = new FilterDescriptor<MaintenanceBoxDataDataTableRow>() { FilteringExpression = (e) => (Check(e)) };
}
 
 
/// <summary>
/// Creates the filter expression.
/// </summary>
/// <param name="instance">The instance.</param>
/// <returns></returns>
public override System.Linq.Expressions.Expression CreateFilterExpression(System.Linq.Expressions.Expression instance)
{
    this.Distinct = this.Column.ColumnFilterDescriptor.DistinctFilter;
    return Filter.CreateFilterExpression(instance);
}
 
 
private bool Check(DataRow row)
{
    var desc = this.Distinct.DistinctValues.ToArray();
 
    if (!desc.Any())
        return true;
 
 
    // NEVER PASS THIS PART OF CODE           
    Debug.Assert(row != null, "Should have found a Row");
    ...           
             
}
 
public FilterDescriptor<MaintenanceBoxDataDataTableRow> Filter { get; private set; }
 
public IDistinctValuesFilterDescriptor Distinct { get; set; }
0
Rossen Hristov
Telerik team
answered on 05 Jun 2012, 06:11 AM
Hi,

When you do this: gridColumn.ClearFilters(); you are effectively clearing everything the user has checked, including the distinct values. Read this for more info. Setting a new filter in the Prepare method is not right. The Prepare method is for preparing the filtering control UI, not for setting filters on RadGridView.

The very best option is to have a your very own custom filtering control which does not inherit from the stock one. This filtering control will have a simle list box with all the distinct values (which you can get from the grid via the GetDistinctValues method as seen here) and then it will use your custom filter descriptor. By inheriting from the stock control, you get the out-of-the-box filtering, which you don't really need, since you are replacing it with your own filtering logic. I am talking about something like this example. If you have your very own custom filtering control you will be in total charge of what is going on and if we make further changes to our stock FilteringControl, which we will definitely do at some point of time -- you will be not affected because you will not be inheriting from it. We are constantly improving our grid and making changes to the stock FilteringControl is imminent. On the other hand, you will have total control over your very own custom filtering control and it will not change. This is definitely the better approach, but it is up to you to decice.

You said that everything was working with the previous version. Can you please send me a runnable sample project with this old implementation, so I can see what exactly you are doing and how it was working with the old version. I will try to see whether your old implementation can be adapted to the new version. I can't promise that this will be possible, but I will take a look to see what can be done.

Regards,
Ross
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Luc
Top achievements
Rank 1
answered on 05 Jun 2012, 12:00 PM
Thank for the information.
1. the reason I was inheriting from your filter control, is to keep the same layout (listbox for distinct values, button title and position) so if you ever changed it il will follows your standard.)
2. for the "runnable sample" you can see the video at this link (http://sdrv.ms/M3teV0). unfortunately the "disctinct value selector" doesnt records in "faststone video capture" ??? so I attach a File for the "selection"

Hope that help,

Any way, I'll implement my own filter control
0
Luc
Top achievements
Rank 1
answered on 05 Jun 2012, 02:12 PM
To continue with my problem, if I create my own implementation of IFilterControl, their is not only the fact that I need ton ensure that the control will look the same in the futur, but I lost the option of "SelectAll" check box... That's wy I was inerits from the "FilteringControl" instance used in your control is "FilteringViewModel" created within the FilterControl and the constructor is "internal" I cannot used this technique...

I think that I must stay with the "FilteringControl" inheritance..
I will try to change the "FilterDescriptor" avec calling the "base.Prepare()" in my filtering control..

Tags
GridView
Asked by
Luc
Top achievements
Rank 1
Answers by
Rossen Hristov
Telerik team
Luc
Top achievements
Rank 1
Share this question
or