How to hide rows bound to GridView?

6 posts, 0 answers
  1. Rob Ainscough
    Rob Ainscough avatar
    172 posts
    Member since:
    Jan 2010

    Posted 14 Oct 2013 Link to this post

    I'm trying to setup a GridView that will hide (not visible) rows (objects) based on some of my own criteria.  A checkbox external to the GridView will drive the logic that makes these rows visible or hidden.

    I assume I can do this one of two way:

    1.  Setup a filter and apply the filter to the Grid?
    2.  LoadingRowDetails and somehow set visibility of row?

    I'm sure this is a very common scenario, can someone give me hints/ideas on how to accomplish this using MVVM?

    EDIT: Tried to setup and bind a filter value, but that doesn't seem to work (grid is not being filter) ...

    <telerik:RadGridView.FilterDescriptors>
    <telerik:FilterDescriptor
    Member="CustomerUnitStatus"
    Operator="IsEqualTo"
    Value="{Binding Path=UnitStatusFilter, Mode=TwoWay, FallbackValue='Occupied', TargetNullValue='Occupied'}"
    IsCaseSensitive="False"/>
    </telerik:RadGridView.FilterDescriptors>

    In my MVVM I have a UnitStatusFilter property I'm still seeing rows in the GridView that are NOT equal.  IsFilteringAllowed=True for the GridView

    Thanks, Rob.
  2. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 15 Oct 2013 Link to this post

    Hi,

    Since the FilterDescriptor is not part of the visual tree you cannot bind it like that in XAML, since its DataContext is not the same as the one of the grid.

    Create a FilterDescriptor in code behind and add it to the FilterDescriptors collection. Kepp its reference. Attach to the PropertyChanged event of your view model and if the changed property is UnitStatusFilter update the FilterDescriptor.Value. Note that the Value you set must be of the same type as the data in the column. 

    I am afraid that this cannot be done entirely through XAML. If you don't want to leave your MVVM pattern you can always embed this code in an attached behavior and set it on the grid.

    More about programmatic filtering you can learn here.

    Regards,
    Rossen Hristov
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  3. DevCraft banner
  4. Rob Ainscough
    Rob Ainscough avatar
    172 posts
    Member since:
    Jan 2010

    Posted 15 Oct 2013 Link to this post

    Can you point me to a code sample (including XAML) for attached behavior?  The link you provided appears to be all code behind.

    Thanks, Rob.
  5. Rob Ainscough
    Rob Ainscough avatar
    172 posts
    Member since:
    Jan 2010

    Posted 15 Oct 2013 Link to this post

    UPDATE:

    I tried using Code Behind, but the filtering is still not happening. I stepped thru the code behind and I can see the data in the Me.UnitSelectionGridView (data binding is happening) and the Filter is added, but the filtering just doesn't seem to work.

    My code behind:

    Private Sub DCUnitSelectionGrid_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
     
        Me.UnitSelectionGridView.FilterDescriptors.SuspendNotifications()
        Dim UnitFilter As New Telerik.Windows.Data.FilterDescriptor("Balance", Telerik.Windows.Data.FilterOperator.IsEqualTo, 0)
        Me.UnitSelectionGridView.FilterDescriptors.Add(UnitFilter)
        Me.UnitSelectionGridView.FilterDescriptors.ResumeNotifications()
     
    End Sub
  6. Rob Ainscough
    Rob Ainscough avatar
    172 posts
    Member since:
    Jan 2010

    Posted 16 Oct 2013 Link to this post

    I have this "partially working" using a behavior - XAML:

    <telerik:RadGridView x:Name="UnitSelectionGridView" AreRowDetailsFrozen="True" AutoGenerateColumns="False" CanUserFreezeColumns="False" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserSortColumns="False" RowIndicatorVisibility="Collapsed" IsReadOnly="False" ShowGroupPanel="False" IsFilteringAllowed="True"
                    ItemsSource="{Binding Path=Customer.CustomerUnits}">
         
        <i:Interaction.Behaviors>
            <DC:RadGridViewGenericFilter x:Name="UnitSelectionFilter" ColumnMember="CustomerUnitStatus" LogicOperator="IsEqualTo"  FilterValue="1" />
        </i:Interaction.Behaviors>

    and the behavior code:

    Imports System.Windows.Interactivity
    Imports Microsoft.Expression.Interactivity
     
    Public Class RadGridViewGenericFilter
        Inherits Behavior(Of Telerik.Windows.Controls.RadGridView)
     
        ' NOTE: ColumnMember = DataMemberBinding value (not the column header)
        Private _ColumnMember As String
        Public Property ColumnMember() As String
            Get
                Return _ColumnMember
            End Get
            Set(ByVal value As String)
                _ColumnMember = value
            End Set
        End Property
     
        Private _LogicOperator As Telerik.Windows.Data.FilterOperator
        Public Property LogicOperator() As Telerik.Windows.Data.FilterOperator
            Get
                Return _LogicOperator
            End Get
            Set(ByVal value As Telerik.Windows.Data.FilterOperator)
                _LogicOperator = value
            End Set
        End Property
     
        Private _FilterValue As String
        Public Property FilterValue() As String
            Get
                Return _FilterValue
            End Get
            Set(ByVal value As String)
                _FilterValue = value
            End Set
        End Property
     
        Protected Overrides Sub OnAttached()
            MyBase.OnAttached()
     
            If Not String.IsNullOrEmpty(ColumnMember) Then
     
                AddHandler AssociatedObject.DataLoading, AddressOf AssociatedObject_DataLoading
     
            End If
     
        End Sub
     
        Protected Overrides Sub OnDetaching()
            MyBase.OnDetaching()
     
            RemoveHandler AssociatedObject.DataLoading, AddressOf AssociatedObject_DataLoading
     
        End Sub
     
        Private Sub AssociatedObject_DataLoading(sender As Object, e As Telerik.Windows.Controls.GridView.GridViewDataLoadingEventArgs)
     
            If AssociatedObject.FilterDescriptors.Count = 0 Then
     
                Dim CustomerUnitStatusColumn As Telerik.Windows.Controls.GridViewColumn = AssociatedObject.Columns(ColumnMember)
                Dim columnDescriptor As Telerik.Windows.Controls.GridView.IColumnFilterDescriptor = CustomerUnitStatusColumn.ColumnFilterDescriptor
     
                With columnDescriptor
                    .SuspendNotifications()
                    .FieldFilter.Filter1.Operator = LogicOperator
                    .FieldFilter.Filter1.Value = FilterValue
                    .ResumeNotifications()
                End With
     
            End If
     
        End Sub
     
    End Class

    So far so good, ColumnFilterDescriptor is setup, Data loads and is filtered.  All MVVM - this is good.  Now, the part I'm stuck at ... how do I set the FilterValue property in my Behavior so that GridView will get updated and display data based on new filter value -- and do this thru my MVVM class?  There is no binding to behavior properties, not supported in SL5, so what are my options? 

    Thanks, Rob.
  7. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 16 Oct 2013 Link to this post

    Hello,

    I have the following idea.

    AssociatedObject is the grid, right. So we have a reference to the grid. From the original binding that you tried to use, I suppose that the DataContext of the grid is an instance of your view model. So what you can do is cast the grid's DataContext property to your view model class. Now you will have a reference to the view model that is the DataContext of the grid, where you can subsribe to its PropertyChanged event and when the respective property changes (I think it was called UnitStatusFilter) -- update the Value of the descriptor. And all of this will be nicely tucked away in the behavior and you will not see it in XAML.

    Or simply add another property to the behavior class and somehow pass the instance of the view model there. I am not sure whether this is possible in SL though.

    There might be other possible approaches to "feeding" a behavior with additional information, i.e. a reference to something that the behavior needs. I suppose that the guys on StackOverflow might have more clever ideas about this task.

    Regards,
    Rossen Hristov
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
Back to Top
DevCraft banner