Sign in to follow this  
Followers 0
abaddon7734

Listview dependant filters

7 posts in this topic

Hi, Im trying to filter out items and subitems in a listview with combos. However each filter should depend on the other filter when it is not empty. Here is an example:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <GuiListView.au3>
#include <GuiComboBox.au3>

GUICreate("filter testing")
GUISetState()

$lv = GUICtrlCreateListView("", 20, 80, 355)
_GUICtrlListView_AddColumn($lv, "column 1", 80)
_GUICtrlListView_AddColumn($lv, "column 2", 80)

loadlist()
Func loadlist()
_GUICtrlListView_DeleteAllItems($lv)
GUICtrlCreateListViewItem("red|circle", $lv)
GUICtrlCreateListViewItem("blue|circle", $lv)
GUICtrlCreateListViewItem("black|square", $lv)
GUICtrlCreateListViewItem("black|triangle", $lv)
EndFunc

GUICtrlCreateLabel("Color", 20, 248, -1, 14)
$combo1 = GUICtrlCreateCombo("", 20, 265, 120)
GUICtrlCreateLabel("Shape", 160, 248, -1, 14)
$combo2 = GUICtrlCreateCombo("", 160, 265, 120)

putdata()
Func putdata()
GUICtrlSetData($combo1, " |red|blue|black")
GUICtrlSetData($combo2, " |circle|square|triangle")
EndFunc
$button = GUICtrlCreateButton(" Clear ", 320, 263)

While 1
$msg = GuiGetmsg()
Switch $msg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $button
GUICtrlSetData($combo1, "")
GUICtrlSetData($combo2, "")
putdata()
loadlist()
Case $combo1, $combo2
Filter(GUICtrlRead($combo1), GUICtrlRead($combo2))
EndSwitch
WEnd

Func Filter($c1, $c2)
_GUICtrlListView_DeleteAllItems($lv)
loadlist()
$itemcount = _GUICtrlListView_GetItemCount($lv)
For $z = $itemcount - 1 To 0 Step -1
$item = _GUICtrlListView_GetItemText($lv, $z)
$subitem = _GUICtrlListView_GetItemText($lv, $z, 1)
If ($item = "" Or $item = $c1) Or ($subitem = "" Or $subitem = $c2) Then
ContinueLoop
Else
_GUICtrlListView_DeleteItem($lv, $z)
EndIf
Next
EndFunc

When i choose "black" it lists the two items containg black correctly, but when i choose square next, it isnt working. Also how do it do it the other way round, if i choose "circle" first and then "red" to work?

Please help :( Ive been trying to solve this from many weeks. Can this be done in a simple way without using that complicated $WM_COMMAND :x and all?

Share this post


Link to post
Share on other sites



I think this should work the way you're looking for.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <GuiListView.au3>
#include <GuiComboBox.au3>
GUICreate("filter testing")
GUISetState()
$lv = GUICtrlCreateListView("", 20, 80, 355)
_GUICtrlListView_AddColumn($lv, "column 1", 80)
_GUICtrlListView_AddColumn($lv, "column 2", 80)
loadlist()
GUICtrlCreateLabel("Color", 20, 248, -1, 14)
$combo1 = GUICtrlCreateCombo("", 20, 265, 120)
GUICtrlCreateLabel("Shape", 160, 248, -1, 14)
$combo2 = GUICtrlCreateCombo("", 160, 265, 120)
putdata()
$button = GUICtrlCreateButton(" Clear ", 320, 263)
While 1
     $msg = GUIGetMsg()
     Switch $msg
          Case $GUI_EVENT_CLOSE
               ExitLoop
          Case $button
               GUICtrlSetData($combo1, "")
               GUICtrlSetData($combo2, "")
               putdata()
               loadlist()
          Case $combo1, $combo2
               Filter(GUICtrlRead($combo1), GUICtrlRead($combo2))
     EndSwitch
WEnd
Func Filter($c1, $c2)
     _GUICtrlListView_DeleteAllItems($lv)
     loadlist()
     $itemcount = _GUICtrlListView_GetItemCount($lv)
     For $z = $itemcount - 1 To 0 Step -1
          $item = _GUICtrlListView_GetItemText($lv, $z)
          $subitem = _GUICtrlListView_GetItemText($lv, $z, 1)
          If ($c1 = "" Or $c1 = $item) Then
             If ($c2 = "" Or $c2 = $subitem) Then
                    ContinueLoop
               Else
                    _GUICtrlListView_DeleteItem($lv, $z)
               EndIf
          Else
               _GUICtrlListView_DeleteItem($lv, $z)
          EndIf
     Next
EndFunc   ;==>Filter
Func loadlist()
     _GUICtrlListView_DeleteAllItems($lv)
     GUICtrlCreateListViewItem("red|circle", $lv)
     GUICtrlCreateListViewItem("blue|circle", $lv)
     GUICtrlCreateListViewItem("black|square", $lv)
     GUICtrlCreateListViewItem("black|triangle", $lv)
EndFunc   ;==>loadlist
Func putdata()
     GUICtrlSetData($combo1, " |red|blue|black")
     GUICtrlSetData($combo2, " |circle|square|triangle")
EndFunc   ;==>putdata

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <GuiListView.au3>
#include <GuiComboBox.au3>

Global $data
$data &= "red|circle#"
$data &= "blue|circle#"
$data &= "black|square#"
$data &= "black|triangle"

$data = StringSplit($data, "#")

GUICreate("filter testing")
GUISetState()
$lv = GUICtrlCreateListView("", 20, 80, 355)
_GUICtrlListView_AddColumn($lv, "column 1", 80)
_GUICtrlListView_AddColumn($lv, "column 2", 80)
GUICtrlCreateLabel("Color", 20, 248, -1, 14)
$combo1 = GUICtrlCreateCombo("", 20, 265, 120)
GUICtrlSetData($combo1, "All|red|blue|black", 'All')
GUICtrlCreateLabel("Shape", 160, 248, -1, 14)
$combo2 = GUICtrlCreateCombo("", 160, 265, 120)
GUICtrlSetData($combo2, "All|circle|square|triangle", 'All')
$button = GUICtrlCreateButton(" Clear ", 320, 263)
Filter()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $button
            GUICtrlSetData($combo1, "All")
            GUICtrlSetData($combo2, "All")
            Filter()
        Case $combo1, $combo2
            Filter()
    EndSwitch
WEnd

Func Filter()
    $c1 = GUICtrlRead($combo1)
    $c2 = GUICtrlRead($combo2)
    _GUICtrlListView_DeleteAllItems($lv)
    For $i = 1 To $data[0]
        $col = StringSplit($data[$i],'|')
        If $c1 <> 'All' And $col[1] <> $c1 Then ContinueLoop
        If $c2 <> 'All' And $col[2] <> $c2 Then ContinueLoop
        GUICtrlCreateListViewItem($data[$i], $lv)
    Next
EndFunc   ;==>Filter

Share this post


Link to post
Share on other sites

Thankyou very much BrewManNH and Zedna! :o Both work perfectly! However Zedna's is the better one.

Thanks a lot you guys, now i can complete that old project! Finally an easy way to make listview filters!

Share this post


Link to post
Share on other sites

@Zedna

I added some more filters but confused on how to validate them in the Filter function.

Suppose there is a listview column containing digits from 1 to 7 and for which there are two combo filters "Min" and "Max", having the same numbers in both of them. Now what i want to do is that if i choose 3 in Min, the listview should display numbers from 3 to 7. Then if i choose 5 in Max, listview should display numbers from 3 to 5. Also the other way round by first choosing Max

If $col[4] is an array of the number values from the listview and $min is the data in Min combo and $max is the one in Max combo filter, what should the testing condition in filter() function be?

Func filter()

_GUICtrlListView_DeleteAllItems($lv)

For $i = 1 To $rowdata[0] - 1
$col = StringSplit($rowdata[$i], '|')

If ($min <> '' And $col[4] < $min) And ($max <> '' And $col[4] > $max) Then ContinueLoop ; <----- This line is not working :(

GUICtrlCreateListViewItem($rowdata[$i], $lv)
Next
Endfunc

The testing condition does not work properly. Can you help me on this?

Thanks

Share this post


Link to post
Share on other sites

Sorry for not posting code. In essence its a "range filter". But Now I almost got it working. Forgot that parentheses are required to group And in If. However there's one little problem.

#include <ComboConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListviewConstants.au3>
#include <StaticConstants.au3>
#include <Guilistview.au3>
#include <ButtonConstants.au3>
#include <Array.au3>
GUICreate("")
GUISetState()
Global $items = " |1|2|3|4|5|6|7"
Global $lv, $rowdata
$lv = GUICtrlCreateListView("digits", 50, 50, 49, 140, -1, $LVS_EX_GRIDLINES)
GUICtrlCreateLabel("Min: ", 134, 58, 25)
GUICtrlCreateLabel("Max: ", 224, 58)
$clear = GUICtrlCreateButton(" clear ", 320, 53)
$filter_min = GUICtrlCreateCombo("", 168, 55, 40)
$filter_max = GUICtrlCreateCombo("", 258, 55, 40)
GUICtrlSetData($filter_min, $items)
GUICtrlSetData($filter_max, $items)

For $i = 1 To 7
GUICtrlCreateListViewItem($i, $lv)
Next
Local $itemcount = _GUICtrlListView_GetItemCount($lv)
For $z = 0 To $itemcount - 1
$rowdata &= _GUICtrlListView_GetItemText($lv, $z, 0) & "|"
Next
$rowdata = StringSplit($rowdata, "|")
_ArrayPop($rowdata)

While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
Exit
Case $filter_min, $filter_max
filter()
Case $clear
clear()
EndSwitch
WEnd

Func filter()
Local $min = GUICtrlRead($filter_min), $max = GUICtrlRead($filter_max)
_GUICtrlListView_DeleteAllItems($lv)
For $q = 1 To $rowdata[0] - 1
If ($min <> ' ' And $rowdata[$q] < $min) Then ContinueLoop
If ($max <> ' ' And $rowdata[$q] > $max) Then ContinueLoop
GUICtrlCreateListViewItem($rowdata[$q], $lv)
Next
EndFunc ;==>filter

Func clear()
_GUICtrlListView_DeleteAllItems($lv)
For $i = 1 To 7
GUICtrlCreateListViewItem($i, $lv)
Next
GUICtrlSetData($filter_min, "")
GUICtrlSetData($filter_max, "")
GUICtrlSetData($filter_min, $items)
GUICtrlSetData($filter_max, $items)
EndFunc ;==>clear

At first run, If you choose empty field (no number) in any combo filter, listview data disappears. But after, if you choose digits, its working. I think there is a conflict with empty data '' and space ' ' in combo filter. I had to add a first space to Global $items = " |1|2|3|4|5|6|7" to show an empty value in combo list. Also inside filter(), i tested with empty and space in If ($min <> ' ' And $rowdata[$q]...

Confused :huh2:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0