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

FilteringUIVisibility property not used

9 Answers 336 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Jason
Top achievements
Rank 1
Jason asked on 13 Oct 2011, 10:17 PM

Regardless of how I attempt to set the visibility for it, I cannot get the FilteringDropDown control within the GridViewHeaderCell for a column bound to a custom type to appear in my RadGridView. Sample code below:

 

Public Class MyClass
  Public Property AnInteger As Integer
  Public Property ACustomObject As MyCustomObject
End Class
  
Public Shared myList As New List(Of MyClass)

<telerik:RadGridView ItemsSource="{Binding myList}"
  <telerik:RadGridView.Columns
    <telerik:GridViewComboBoxColumn
      DataMemberBinding="{Binding ACustomObject}"
      ItemsSource="{Binding Source={StaticResource PredfinedListOfMyCustomObject}"
      DisplayMemberPath="Name"
      IsCustomSortingEnabled="True"
      <telerik:GridViewComboBoxColumn.HeaderCellStyle
        <Style TargetType="{x:Type telerik:GridViewHeaderCell}" BasedOn="{StaticResource {x:Type telerik:GridViewHeaderCell}}"
          <Setter Property="FilteringUIVisibility" Value="Visible"/> 
        </Style
      </telerik:GridViewComboBoxColumn.HeaderCellStyle
      <telerik:GridViewComboBoxColumn.FilteringControl
        <local:CustomFilter/> 
      </telerik:GridViewComboBoxColumn.FilteringControl
    </telerik:GridViewComboBoxColumn
  </telerik:RadGridView.Columns
</telerik:RadGridView>

Both with and without the HeaderCellStyle I do not get the FilteringDropDown. If I run the application with WPF Inspector or Snoop and change the FilteringUIVisibility from collapsed (which it always is) to visible (which the default is and what I set it to manually) then the FilteringDropDown appears and I can use my custom filter. I am assuming some code in the control is overriding my styling based on the non-standard object type (which is why I have custom sorting on the column as well) but I cannot figure out how to avoid it or restore the FilteringDropDown.

9 Answers, 1 is accepted

Sort by
0
Vanya Pavlova
Telerik team
answered on 17 Oct 2011, 07:09 PM
Hi Jason,


Generally you may access the FilteringDropDown through predefining the template of GridViewHeaderCell or in code-behind using the ChildrenOfType extension method.
However I am not quite sure how this works in your case.
Will you please share with us the source of your custom filtering control? 



Best wishes,
Vanya Pavlova
the Telerik team

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

0
Jason
Top achievements
Rank 1
answered on 18 Oct 2011, 02:35 PM
Vanya,

I have since determined that I do not need to use a custom filter control for my objects as the standard one works just fine as long as I set the FilteringUIVisibility to visible with WPF Inspector or Snoop. The PART_DistinctValuesList list gets populated properly with the DisplayMemberPath values from the GridViewComboBoxColumn and does the filtering correctly.

I shouldn't need to re-template the GridViewHeaderCell as the sole purpose of the FilteringUIVisibility property is to set the visibility of the FilteringDropDown; the background code just seems to be overriding my styling at some point and setting it to collapsed based on type. I need  a way to disable or work around this behaviour, preferably in XAML but in code-behind if need be.

Jason.
0
Jason
Top achievements
Rank 1
answered on 19 Oct 2011, 06:09 PM
Vanya,

Instead of trying to work around this, I have submitted a feature request ticket to add a GridViewColumn.IsCustomFilteringEnabledProperty so that filtering will behave like sorting when it comes to bound objects that cannot be cast to System.Type.

Jason.
0
Nedyalko Nikolov
Telerik team
answered on 20 Oct 2011, 02:47 PM
Hi Jason,

Indeed FilteringUIVisibility depends on that if this particular column can be filtered or not (underlying property implements IComparable or IEquatable). We will fix this behavior, but I think that the best approach will be to show FilteringUI (funnel) if custom filtering control is set (and we will not need IsCustomFilteringEnabled property).
The fix will be included in the next internal build (Monday 24 Oct).

Greetings,
Nedyalko Nikolov
the Telerik team

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

0
Jason
Top achievements
Rank 1
answered on 20 Oct 2011, 03:04 PM
Nedyalko,

I'm sorry to see my feature request was closed. The underlying object I am binding to does in fact already implement both the IComparable and IEquatable interfaces. Both the IsFilterable and IsSortable properties return true. However, the CanSort function only returns true when I set IsCustomSortingEnabled to true and the CanFilter function never returns true. Also, as I stated previously, I am no longer using a custom filter so the proposed solution will still not be any help. I really think that adding a IsCustomFilteringEnabled property that then affects the CanFilter function so that it works in the same way that sorting works will be the best solution; and the sorting code already provides a template for what needs to be done.

Jason.
0
Nedyalko Nikolov
Telerik team
answered on 21 Oct 2011, 09:33 AM
Hi Jason,

Could you please elaborate a little bit how will you perform "CustomFiltering" without custom filter control, and why my suggestion will not solve your problem?

The only reason that CanFilter() function always retutn false may be that you are using GridViewColumn instead of GridViewBoundColumnBase or GridViewDataColumn. GridViewColumn.CanFilter() always return false, because GridViewColumn class has no DataType property, and we cannot determinate if filtering is possible.
I'm almost sure that if you change GridViewColumn with GridViewDataColumn you will get the desired result.

All the best,
Nedyalko Nikolov
the Telerik team

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

0
Jason
Top achievements
Rank 1
answered on 31 Oct 2011, 04:10 PM
Nedyalko,

The example I posted at the top uses a data bound GridViewComboBoxColumn (which inherits from GridViewBoundColumnBase). Without seeing your actual code, I can't say exactly how it determines when CanFilter and CanSort return true. What I do know is that the column returns CanSort as false unless I set IsCustomSortingEnabled on it. Even without writing any custom sorting code or handling the Sorting event of the GridView, the column is then sortable in the UI as the underlying bound object does have IComparable and IEquatable interfaces.

This behaviour could work the same way for filtering. For whatever reason CanFilter is false and overriding it with something like IsCustomFilteringEnabled would allow me to filter using the stock FilteringControl (which works perfectly when I set FilteringUIVisibility manually in Snoop). Your suggestion would work fine if I had a need for a custom filter but I do not and simply need to be able to do what I can already for sorting but for filtering instead.

Jason.
0
Accepted
Rossen Hristov
Telerik team
answered on 20 Dec 2012, 10:23 AM
Hi,

Here is how a column determines whether it CanFilter():

public override bool CanFilter()
{
    if (this.DataControl == null)
    {
        return false;
    }
 
    if (!this.DataControl.IsFilteringAllowed)
    {
        return false;
    }
 
    if (!this.IsFilterable)
    {
        return false;
    }
 
    if (this.FilteringControl != null)
    {
        // The developer has provided a custom FilteringControl and
        // he will be responsible for filtering.
        return true;
    }
 
    if (this.EffectiveFilteringType == null)
    {
        return false;
    }
 
    if (this.EffectiveFilteringType.CanFilter() || this.IsBoundToDynamicType())
    {
        return true;
    }
 
    return false;
}

So in the end, the CanFilter depends on whether the EffectiveFilteringType.CanFilter().

Each GridViewColumn has a property called FilterMemberPath. This property can be used to tell the column to filter a property different from the one it displays in its cells.

The EffectiveFilteringType is determined as follows. If there is no FilterMemberPath set on the column it is the the type of data that the column is bound to. If you have set FilterMemberPath in order to make a column show one property, but filter on another, then the EffectiveFilteringType is the type of the property set via FilterMemberPath.

Once the EffectiveFilteringType is known, here is how we determine whether a Type can be filtered by the .NET Framework, i.e. whether we can create a LINQ Where clause involving this property:

internal static bool CanFilter(this Type source)
{
    if (source == null) return false;
 
    Type typeToCheck = Nullable.GetUnderlyingType(source) ?? source;
 
    return typeToCheck.ImplementsIEquatable() || typeToCheck.ImplementsIComparable();
}

So if the EffectiveFilteringType is neither IEquatable or IComparable, we cannot build a LINQ expression that will use it. For example:

var result = customers.Where(customer.Property > <<something>>);

If Property is of a Type which is neither Equatable or Comparable, then the .NET Framework does not know how to compare the left and the rigth side of the equation. The above Lambda will crash because it does not know how to compare the left and the right side.

In order to enable filtering on a custom type, you can follow this article which explains how to implement the needed interfaces on your Type so that the .NET Framework knows how to compare instances of your Type for the purpose of Filtering and Sorting.

I hope this helps.

Greetings,
Rossen Hristov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Jason
Top achievements
Rank 1
answered on 20 Dec 2012, 07:24 PM
Rossen,

Thank you for the reply. I guess things have changed a little in the last year and based on your answer I was able to make it work. Initially it did not work as we did not quite implement the interfaces as you anticipate in your code but some additional code in our classes gets us there. I have included the original cases that failed below that should have worked:

Public MustInherit Class ExampleBase
    Implements IEquatable(Of ExampleBase)
    Implements IComparable(Of ExampleBase)
  
    Public Property Name As String
    Public Overloads Function Equals(other As ExampleBase) As Boolean Implements System.IEquatable(Of ExampleBase).Equals
        Return String.Equals(Me.Name, other.Name)
    End Function
    Public Function CompareTo(other As ExampleBase) As Integer Implements System.IComparable(Of ExampleBase).CompareTo
        Return String.Compare(Me.Name, other.Name)
    End Function
End Class
  
Public Class ExampleDerived
    Inherits ExampleBase
  
End Class
We then bind our column to the ExampleDerived property of an object. There are two things to note. First, that ExampleDerived does not implement an IEquality(Of ExampleDerived) interface but all equality checks work based on the inherited class. Second, that we do not implement the IComparable interface but IComparable(Of ExampleBase) which works with your example LINQ query.

Implementing either of the IEquatable(Of ExampleDerived) or IComparable interfaces allowed the filtering to work so that is the solution we will go with. As a side note, implementing IComparable also allows us to drop the IsCustomSortingEnabled property which makes sense given how the filtering check works. It should also be able to work with IComparable(Of ExampleBase) or IComparable(Of ExampleDerived).

Thanks,
Jason
Tags
GridView
Asked by
Jason
Top achievements
Rank 1
Answers by
Vanya Pavlova
Telerik team
Jason
Top achievements
Rank 1
Nedyalko Nikolov
Telerik team
Rossen Hristov
Telerik team
Share this question
or