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

RadListControl and RadGridView FIlters

8 Answers 210 Views
ListControl
This is a migrated thread and some comments may be shown as answers.
Dean Allan
Top achievements
Rank 1
Dean Allan asked on 13 Feb 2011, 09:52 PM
Hello,

I was hoping someone could shed some light on this situation.

I have a RadPageView with a RadListControl inside.  The list control is populated from a sql table that contains potential 'status' setting for a recordset that is filling a RadGridView also on the same page.  I have the list control MultiSelect set to 'Simple'. The idea is a fast, multi-select filter for the radgrid.

So as with most issues, 90% works great.  Using RadListControl1.SelectedIndexChanged as my event handler I am able to create a filter for the radgrid using OR to allow filtering for multiple status at one time.   If the user clicks status 'a' then status 'b' then status 'c' the Radgrid filters and only shows 'A',then adds 'B',then 'C'.  Perfect! (status LIKE 'A' or status LIKE 'B' or status LIKE 'C' is  the expression I end up with, again perfect)

Here is where is problem lies.  When a user un-selects items in the RadListControl in reverse order (Add, A,B,C then Remove C,B,A) things seem to work, the event handler fires properly.  However, if the user un-selects items in any other order the event wont fire (Add A,B,C  then unselect A,B,C).  I'm guessing this is by design.  Although I have a loop with a message box showing the RadLIstControl items each time the event fires (for debugging).  I don't know if this might have some unseen effect on the control.

So I am wondering, is there a solution for this situation, either using the RadListControl (it's fast) or would there be a better method, I just can't seem to get my head around this one.  My code is in VB if that matters.

Thanks in advance!

Dean.

8 Answers, 1 is accepted

Sort by
0
Accepted
Richard Slade
Top achievements
Rank 2
answered on 14 Feb 2011, 12:59 AM
Hi Dean,

Here's another way. Subscribe to the RadPropertyChanged for each item and capture the selected propert

For Each item As RadListDataItem In Me.RadListControl1.Items
    AddHandler item.RadPropertyChanged, AddressOf RadListControl_RadPropertyChanged
Next

Private Sub RadListControl_RadPropertyChanged(ByVal sender As Object, ByVal e As RadPropertyChangedEventArgs)
    If e.Property.Name = "Selected" Then
        Dim item As RadListDataItem = CType(sender, RadListDataItem)
        MessageBox.Show(item.Text & " is selected: " & item.Selected.ToString())
    End If
End Sub

Hope that helps
Richard
0
Dean Allan
Top achievements
Rank 1
answered on 15 Feb 2011, 06:38 AM
Hi Richard,

Thanks for the input.

Just so I know, based on what I see, the first snippet manually adds an event handler to each item in the ListControl on the form load.  The second is the Sub that gets called. I notice there isn't a 'handles' in the sub, I guess this isn't necessary since the event handler is called directly?

So far your suggestion is working well.  I noticed the selecteditems.count() isn't accurate at the time this event fires though;  for example, I show a count of 2 when I have one selected.  I can figure out a workaround but is there another method related to your solution to iterate the selected collection?

Thanks again! 

Dean.

Here is an example of the code I am working on. I rem'ed out the the loop that wasn't working for debugging.  I tried both 1 and 0 for the loop.
Private Sub RadListControl_RadPropertyChanged(ByVal sender As Object, ByVal e As RadPropertyChangedEventArgs)
       If e.Property.Name = "Selected" Then
           'Dim x As Integer
           Dim item As RadListDataItem = CType(sender, RadListDataItem)
           ' MessageBox.Show(item.Text & " is selected: " & item.Selected.ToString())
           Me.RadGridView1.FilterDescriptors.Clear()
           Me.RadGridView1.FilterDescriptors.LogicalOperator = FilterLogicalOperator.Or
 
           ' For x = 1 To Me.RadListControl1.SelectedItems.Count()
           MsgBox(RadListControl1.SelectedItems.Count())
           Me.RadGridView1.FilterDescriptors.Add("status", FilterExpression.BinaryOperation.[OR], item.Text)
           ' Next
 
       End If
   End Sub

0
Richard Slade
Top achievements
Rank 2
answered on 15 Feb 2011, 08:57 AM
Hi Dean,

No, you don't need a Handler for those that have had an event handler manually added.
The reason that the items count seems incorrect on the de-selection is because when you message out the selection the prioperty has changed but appear still to be selected.
You can get over this with the following
Declare a private int
Private m_ItemsCount As Integer = 0

Private Sub RadListControl_RadPropertyChanged(ByVal sender As Object, ByVal e As RadPropertyChangedEventArgs)
    If e.Property.Name = "Selected" Then
        If CType(sender, RadListDataItem).Selected Then
            m_ItemsCount = m_ItemsCount + 1
        Else
            m_ItemsCount = m_ItemsCount - 1
        End If
        MessageBox.Show(m_ItemsCount.ToString())
    End If
End Sub

Hope thast helps but let me know if you need anything else
Richard
0
Dean Allan
Top achievements
Rank 1
answered on 15 Feb 2011, 12:20 PM
Hey Richard,

That did make the count correct but I still keep hitting a brick wall.

Let me ask this; What is the best way to add/remove a filter to a datagrid using a ListControl with multiple simple select?  

Thanks again for the assistance!

Dean.

This is what I have so far but it seems the event is called several times and i am at a loss.
Private Sub RadListControl_RadPropertyChanged(ByVal sender As Object, ByVal e As RadPropertyChangedEventArgs)
    Me.RadGridView1.FilterDescriptors.Clear() ' i assumed this sub was only called once per click. This clears the filter and rebuilds it's rather than pop items on and off.
    If CType(sender, RadListDataItem).Selected Then
        Dim item As RadListDataItem = CType(sender, RadListDataItem)
        Me.RadGridView1.FilterDescriptors.LogicalOperator = FilterLogicalOperator.Or
        Me.RadGridView1.FilterDescriptors.Add("status", FilterExpression.BinaryOperation.[OR], Me.RadListControl1.SelectedItems.Item(x).ToString)
    End If
End Sub



0
Accepted
Richard Slade
Top achievements
Rank 2
answered on 15 Feb 2011, 01:34 PM
Hi Dean,

Ok, I've put togeether a small sample for you. I think in this case it's best to use Custom Filtering and I've also changed slightly the handler to pick up the click event rather than the RadPropertyChanged. All seems to work fine but let me know if you have any questions

Designer File
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form
  
    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub
  
    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer
  
    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Dim RadListDataItem1 As Telerik.WinControls.UI.RadListDataItem = New Telerik.WinControls.UI.RadListDataItem()
        Dim RadListDataItem2 As Telerik.WinControls.UI.RadListDataItem = New Telerik.WinControls.UI.RadListDataItem()
        Dim RadListDataItem3 As Telerik.WinControls.UI.RadListDataItem = New Telerik.WinControls.UI.RadListDataItem()
        Dim RadListDataItem4 As Telerik.WinControls.UI.RadListDataItem = New Telerik.WinControls.UI.RadListDataItem()
        Dim RadListDataItem5 As Telerik.WinControls.UI.RadListDataItem = New Telerik.WinControls.UI.RadListDataItem()
        Me.RadListControl1 = New Telerik.WinControls.UI.RadListControl()
        Me.RadGridView1 = New Telerik.WinControls.UI.RadGridView()
        CType(Me.RadListControl1, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.RadGridView1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'RadListControl1
        '
        Me.RadListControl1.CaseSensitiveSort = True
        Me.RadListControl1.Dock = System.Windows.Forms.DockStyle.Left
        RadListDataItem1.Text = "Available"
        RadListDataItem1.TextWrap = True
        RadListDataItem2.Text = "Unavailable"
        RadListDataItem2.TextWrap = True
        RadListDataItem3.Text = "Busy"
        RadListDataItem3.TextWrap = True
        RadListDataItem4.Text = "Meeting"
        RadListDataItem4.TextWrap = True
        RadListDataItem5.Text = "Holiday"
        RadListDataItem5.TextWrap = True
        Me.RadListControl1.Items.Add(RadListDataItem1)
        Me.RadListControl1.Items.Add(RadListDataItem2)
        Me.RadListControl1.Items.Add(RadListDataItem3)
        Me.RadListControl1.Items.Add(RadListDataItem4)
        Me.RadListControl1.Items.Add(RadListDataItem5)
        Me.RadListControl1.Location = New System.Drawing.Point(0, 0)
        Me.RadListControl1.Name = "RadListControl1"
        Me.RadListControl1.Size = New System.Drawing.Size(120, 282)
        Me.RadListControl1.TabIndex = 0
        Me.RadListControl1.Text = "RadListControl1"
        '
        'RadGridView1
        '
        Me.RadGridView1.Dock = System.Windows.Forms.DockStyle.Fill
        Me.RadGridView1.Location = New System.Drawing.Point(120, 0)
        Me.RadGridView1.Name = "RadGridView1"
        Me.RadGridView1.Size = New System.Drawing.Size(204, 282)
        Me.RadGridView1.TabIndex = 0
        Me.RadGridView1.Text = "RadGridView1"
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(324, 282)
        Me.Controls.Add(Me.RadGridView1)
        Me.Controls.Add(Me.RadListControl1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        CType(Me.RadListControl1, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.RadGridView1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)
  
    End Sub
    Friend WithEvents RadListControl1 As Telerik.WinControls.UI.RadListControl
    Friend WithEvents RadGridView1 As Telerik.WinControls.UI.RadGridView
  
End Class

Form1.vb
Imports System.ComponentModel
Imports Telerik.WinControls.UI
Imports Telerik.WinControls
  
Public Class Form1
  
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim list As New BindingList(Of MyStatus)
        list.Add(New MyStatus("Richard", "Available"))
        list.Add(New MyStatus("Bob", "Holiday"))
        list.Add(New MyStatus("Chris", "Holiday"))
        list.Add(New MyStatus("Stew", "Unavailable"))
        list.Add(New MyStatus("Pete", "Busy"))
        list.Add(New MyStatus("Ester", "Busy"))
        list.Add(New MyStatus("Harriet", "Meeting"))
        list.Add(New MyStatus("Leisl", "Available"))
        list.Add(New MyStatus("Tonia", "Busy"))
  
        Me.RadGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill
        Me.RadGridView1.EnableFiltering = True
        Me.RadGridView1.ShowFilteringRow = False
        Me.RadGridView1.EnableCustomFiltering = True
        Me.RadListControl1.SelectionMode = SelectionMode.MultiSimple
        Me.RadGridView1.DataSource = list
  
  
        For Each item As RadListDataItem In Me.RadListControl1.Items
            AddHandler item.VisualItem.Click, AddressOf RadListControl1_ItemClick
        Next
    End Sub
  
    Private Sub RadListControl1_ItemClick(ByVal sender As Object, ByVal e As EventArgs)
        Me.RadGridView1.MasterTemplate.Refresh()
    End Sub
  
    Private Sub RadGridView1_CustomFiltering(ByVal sender As System.Object, ByVal e As Telerik.WinControls.UI.GridViewCustomFilteringEventArgs) Handles RadGridView1.CustomFiltering
        If Me.RadListControl1.SelectedItems.Count = 0 Then
            e.Visible = True
            Return
        End If
  
        e.Visible = False
        Dim found As Boolean
        For Each item As RadListDataItem In Me.RadListControl1.SelectedItems
            If String.Equals(item.Text, e.Row.Cells("Status").Value.ToString()) Then
                found = True
                Exit For
            End If
        Next
        e.Visible = found
    End Sub
  
  
End Class
  
Public Class MyStatus
  
    Public Sub New(ByVal name As String, ByVal status As String)
        Me.Name = name
        Me.Status = status
    End Sub
  
    Public Property Name As String
    Public Property Status As String
End Class

and here is a small video of it working
Hope that helps
Richard
0
Dean Allan
Top achievements
Rank 1
answered on 16 Feb 2011, 03:55 AM
Hey Richard,

Thanks again for the assistance. The last example was great!

I decided with a hybrid of your original offering.  I like the filter method for RadGrid I was using (mainly because I understood it), it was the functionality of standard listcontrol event handler that was holding me up.

Your first example really solved the problem.  It provided me with an accurate representation of the events going on with the listcontrol. Taking that data, I created a second Sub that will handle popping the stack (an array) and then i'll build a new set of filters. It's a bit old school but should do the trick. It also let's me add other fields besides status to the filters.

Something like this.

Private Sub RadListControl_RadPropertyChanged(ByVal sender As Object, ByVal e As RadPropertyChangedEventArgs)
      If e.Property.Name = "Selected" Then
          Dim item As RadListDataItem = CType(sender, RadListDataItem)
          ModifyFilter(item.Text, item.Selected.ToString(),"status")
      End If
  End Sub
  Private Sub ModifyFilter(ByVal status As String, ByVal action As String, ByVal field as String)
      If action = "True" Then
          MsgBox("Add " & status) ' for debugging only
          'add to the stack
      Else
          MsgBox("Remove " & status) ' for debugging only
          'pop the stack
      End If
      'clear and rebuild the filters from the stack.
  End Sub


Thanks again, 

Dean.
0
Dean Allan
Top achievements
Rank 1
answered on 16 Feb 2011, 04:48 AM
Hey Richard,

Here is my final code I came up with.  So far it seems to work. Thanks again, couldn't have gotten this far without your help!

Private Sub RadListControl_RadPropertyChanged(ByVal sender As Object, ByVal e As RadPropertyChangedEventArgs)
      If e.Property.Name = "Selected" Then
          Dim item As RadListDataItem = CType(sender, RadListDataItem)
          ModifyFilter(item.Text, item.Selected.ToString())
      End If
  End Sub
  Private Sub ModifyFilter(ByVal newstatus As String, ByVal newaction As String)
      If newaction = "True" Then
          Me.RadGridView1.FilterDescriptors.LogicalOperator = FilterLogicalOperator.Or
          Me.RadGridView1.FilterDescriptors.Add("status", FilterExpression.BinaryOperation.[OR], newstatus)
      Else
          For Each FilterExpression In RadGridView1.FilterDescriptors
              If FilterExpression.Value = newstatus Then
                  Me.RadGridView1.FilterDescriptors.Remove(FilterExpression)
                  Exit For
              End If
          Next
          If RadGridView1.FilterDescriptors.Count = 0 Then ' check to see if all the filters are gone then clear if so.
              RadGridView1.FilterDescriptors.Clear()
          End If
      End If
  End Sub
0
Richard Slade
Top achievements
Rank 2
answered on 16 Feb 2011, 08:42 AM
Hi Dean,

Glad that you have this all sorted now. I'm glad i could help. It's also good to get some feedback and see your final version. Nothing wrong with it, but do have a look at the demos on your PC too for the Custom Filtering. The custom filtering is quite simple but powerful and is really useful for these situations which you may find useful in the future. Anyway, glad you have it all working now.
All the best
Richard
Tags
ListControl
Asked by
Dean Allan
Top achievements
Rank 1
Answers by
Richard Slade
Top achievements
Rank 2
Dean Allan
Top achievements
Rank 1
Share this question
or