Checked Items in ListBox lost after filtering

Ask questions about creating Graphical User Interfaces (GUI) in PowerShell and using WinForms controls.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
This topic is 2 years and 2 months old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked
User avatar
Dead-Red02
Posts: 6
Last visit: Sat Feb 03, 2024 7:35 am
Answers: 1

Checked Items in ListBox lost after filtering

Post by Dead-Red02 »

Hello All,

I use PowerShell Studio 2021 5.8.196.0 (64bits) on Windows 10 64bits

On my projet, then the form is loaded i populate the CheckedListBox2 with data getting from Postgresql database.
  1. #Affichage des accessoires
  2. try
  3. {
  4.     $result_all_Accessories = Get-ODBC-Data -query $query_SC_All_Accessories
  5.     #create a datatable to bind to our combobox
  6.     $datatable_result_all_Accessories = New-Object system.Data.DataTable
  7.     #Define Columns
  8.     $col1_result_all_Accessories = New-Object system.Data.DataColumn "Value", ([string])
  9.     $col2_result_all_Accessories = New-Object system.Data.DataColumn "Text", ([string])
  10.     $col3_result_all_Accessories = New-Object system.Data.DataColumn "Price", ([double])
  11.     $col4_result_all_Accessories = New-Object system.Data.DataColumn "Provider", ([string])
  12.     $col5_result_all_Accessories = New-Object system.Data.DataColumn "Type", ([string])
  13.     #add columns to datatable
  14.     $datatable_result_all_Accessories.columns.add($col1_result_all_Accessories)
  15.     $datatable_result_all_Accessories.columns.add($col2_result_all_Accessories)
  16.     $datatable_result_all_Accessories.columns.add($col3_result_all_Accessories)
  17.     $datatable_result_all_Accessories.columns.add($col4_result_all_Accessories)
  18.     $datatable_result_all_Accessories.columns.add($col5_result_all_Accessories)
  19.     foreach ($row1_result_all_Accessories in $result_all_Accessories)
  20.     {
  21.         $row_result_all_Accessories = $datatable_result_all_Accessories.NewRow()
  22.         $row_result_all_Accessories.Text = (($row1_result_all_Accessories.$column_SC_Accessories) + " ( " + $row1_result_all_Accessories.$column_SC_Accessories_Price + " $Global_Currency_Code )")
  23.         $row_result_all_Accessories.Value = $row1_result_all_Accessories.sc_it_Accessoriesid
  24.         $row_result_all_Accessories.Price = $row1_result_all_Accessories.$column_SC_Accessories_Price
  25.         $row_result_all_Accessories.Provider = $row1_result_all_Accessories.$column_SC_Accessories_Providers
  26.         $row_result_all_Accessories.Type = $row1_result_all_Accessories.$column_SC_Accessories_Types
  27.         $datatable_result_all_Accessories.Rows.Add($row_result_all_Accessories)
  28.     }
  29.     $checkedlistbox2.ValueMember = "Value"
  30.     $checkedlistbox2.DisplayMember = "Text"
  31.     $checkedlistbox2.DataSource = $datatable_result_all_Accessories
  32. }
  33. catch { }
I have add a control on Itemcheck to get all checked items :
  1. $checkedlistbox2_ItemCheck = [System.Windows.Forms.ItemCheckEventHandler]{
  2.     #$Script:items = $checkedlistbox2.CheckedIndices #DOES NOT RETRIEVE THE CORRECT INDEX IF THERE ARE FILTERING ITEMS
  3.     $Script:items = $checkedlistbox2.CheckedItems
  4. }
by Dead-Red02 » Sat Jan 08, 2022 4:05 pm
Ok i have solved it.

Thank's for your help, after reading your post, i stopped to set/reset back each time the datasource.

Errors :

In datatable, i set all time my id (integer) to [string] !
==>

Code: Select all

$col1_result_all_Accessories = New-Object system.Data.DataColumn "Value", ([int])
I changed all the code in Itemcheck :
To keep values was selected before filter, i use global var : "$Script:Attribution_IT_Accessories_Checked_Items"
This var is set in global as follow : $Script:Attribution_IT_Accessories_Checked_Items = @("")

Code: Select all

$checkedlistbox2_ItemCheck = [System.Windows.Forms.ItemCheckEventHandler]{
if ($_.NewValue -eq 'Checked')
{
# If the new checked value is not present in $Script:Attribution_IT_Accessories_Checked_Items i add it
if ($checkedlistbox2.Items.Value[$_.Index] -notin $Script:Attribution_IT_Accessories_Checked_Items)
{
$Script:Attribution_IT_Accessories_Checked_Items += @($checkedlistbox2.Items.Value[$_.Index])
}
}
else
{
$Script:Attribution_IT_Accessories_Checked_Items = @($Script:Attribution_IT_Accessories_Checked_Items | Where-Object { $_ -ne $checkedlistbox2.SelectedItem.Value })
}

}
My code in $combobox3.SelectedValue was good

I have change all code in combobox3_SelectionChangeCommitted

Code: Select all

$Filter_Accessories_Provider_V = 'Provider = ' + $combobox3.SelectedValue
if ($combobox4.SelectedValue)
{
$Filter_Accessories_Type_V = 'Type = ' + $combobox4.SelectedValue
$datatable_result_all_Accessories.defaultview.rowfilter = "$Filter_Accessories_Provider_V AND $Filter_Accessories_Type_V"
}
else
{
$datatable_result_all_Accessories.defaultview.rowfilter = "$Filter_Accessories_Provider_V"
}
foreach($Item_Accessories in $Script:Attribution_IT_Accessories_Checked_Items)
{
for ($i_Accessories = 0; $i_Accessories -lt $checkedlistbox2.Items.Value.Count; $i_Accessories++)
{
if ($Item_Accessories -eq ($checkedlistbox2.Items.Value[$i_Accessories]))
{
$checkedlistbox2.SetItemChecked($i_Accessories, $True)
}
}
}
To reset filter i changed the code too :

Code: Select all

$button4_Click = {
$checkedlistbox2.DataSource.defaultview.rowfilter = ""
foreach ($Item_Accessories in $Script:Attribution_IT_Accessories_Checked_Items)
{
for ($i_Accessories = 0; $i_Accessories -lt $checkedlistbox2.Items.Value.Count; $i_Accessories++)
{
if ($Item_Accessories -eq ($checkedlistbox2.Items.Value[$i_Accessories]))
{
$checkedlistbox2.SetItemChecked($i_Accessories, $True)
}
}
}
$combobox4.DataSource = $null
$combobox3.DataSource = $null
}
And now, all works fine !

I would like to say Thank's to Jvierra for his help and responses of MANY topics on this forum that have helped me on this problem and others. And second thank's to Sapien for this GREATEST software !
Go to full post
User avatar
Dead-Red02
Posts: 6
Last visit: Sat Feb 03, 2024 7:35 am
Answers: 1

Re: Checked Items in ListBox lost after filtering

Post by Dead-Red02 »

(i must add second post to continue because i can't create topic with all my code without obtain error from you forum)

From a combobox list, when you click on it (combobox4), i get specific Types at accessories getting from same database :
(and another combobox3 to get Providers)
  1.     #TODO: Place custom script here $column_SC_Accessories_Types
  2.     if ($combobox3.SelectedValue)
  3.     {
  4.         $Filter_Accessories += (' AND ' + $column_SC_Accessories_Providers + ' = ' + $combobox3.SelectedValue)
  5.     }
  6.     $query_all_Accessories_Settings_Types = 'SELECT ' + $column_SC_Settings_Typesid + ', ' + $column_SC_Settings_Types + ' FROM ' + $Table_SC_Settings_Types + ' where ' + $column_SC_Settings_Typesid + ' IN ( SELECT DISTINCT ' + $column_SC_Accessories_Types + ' FROM ' + $Table_SC_Accessories + ' where ' + $Table_SC_Accessories + '.displayed is TRUE ' + $Filter_Accessories + ' ) order by ' + $column_SC_Settings_Types + ' ASC;'
  7.     $attributions_it_comments_richtextbox.Text = $query_all_Accessories_Settings_Types
  8.     $result_all_Accessories_Settings_Types = Get-ODBC-Data -query $query_all_Accessories_Settings_Types
  9.     #create a datatable to bind to our combobox
  10.     $datatable_result_all_Settings_Types = New-Object system.Data.DataTable
  11.     #Define Columns
  12.     $col1_result_all_Settings_Types = New-Object system.Data.DataColumn "Value", ([string])
  13.     $col2_result_all_Settings_Types = New-Object system.Data.DataColumn "Text", ([string])
  14.     #add columns to datatable
  15.     $datatable_result_all_Settings_Types.columns.add($col1_result_all_Settings_Types)
  16.     $datatable_result_all_Settings_Types.columns.add($col2_result_all_Settings_Types)
  17.     foreach ($row1_result_all_Settings_Types in $result_all_Accessories_Settings_Types)
  18.     {
  19.         $row_result_all_Settings_Types = $datatable_result_all_Settings_Types.NewRow()
  20.         $row_result_all_Settings_Types.Text = $row1_result_all_Settings_Types.$column_SC_Settings_Types
  21.         $row_result_all_Settings_Types.Value = $row1_result_all_Settings_Types.$column_SC_Settings_Typesid
  22.         $datatable_result_all_Settings_Types.Rows.Add($row_result_all_Settings_Types)
  23.     }
  24.     $combobox4.ValueMember = "Value"
  25.     $combobox4.DisplayMember = "Text"
  26.     $combobox4.DataSource = $datatable_result_all_Settings_Type
Then when you have selected data from a combobox (3 or 4) the CheckedListBox1 is uptaded to display only value with the specific provider or types chosen in combobox
  1.         $datatable_result_all_Accessories.defaultview.rowfilter = 'Provider = 0'
  2.     $checkedlistbox2.DataSource = $datatable_result_all_Accessories
  3.     $checkedlistbox2.ValueMember = "Value"
  4.     $checkedlistbox2.DisplayMember = "Text"
  5.     #Pour chaque valeur récupérée on coche l'item   
  6.     foreach ($item in $Script:items)
  7.     {
  8.         #$CheckedListBox2.SetItemChecked($CheckedListBox2.Items.IndexOf($Item), $true);
  9.         $checkedlistbox2.SetItemCheckState($checkedlistbox2.Items.IndexOf($Item))
  10.         $attributions_it_comments_richtextbox.Text = $item
  11.     }
And i have button (button4) when you click on it, i reset filter (type and provider and combobox 3&4) to obtain the inital list (in datatable)
  1.     $checkedlistbox2.DataSource.defaultview.rowfilter = ""
  2.     foreach ($item in $Script:items.Value)
  3.     {
  4.         #$CheckedListBox2.SetItemChecked($CheckedListBox2.Items.IndexOf($Item), $true);
  5.         $checkedlistbox2.SetItemCheckState($checkedlistbox2.Items.IndexOf($Item))
  6.         $attributions_it_comments_richtextbox.Text = $item
  7.     }
  8.     $combobox4.DataSource = $null
  9.     $combobox3.DataSource = $null
All works fine !

But Then you add a filter, or reset filter i lost the Checked Items.

Do you know how i can set checked items when items is present in my $Script:items ?

Thank you very much in advance
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Checked Items in ListBox lost after filtering

Post by jvierra »

You would have to code a method to reset checked items.
User avatar
Dead-Red02
Posts: 6
Last visit: Sat Feb 03, 2024 7:35 am
Answers: 1

Re: Checked Items in ListBox lost after filtering

Post by Dead-Red02 »

My problem is not to reset but to keep Checked Value(or text or item) after you have filter (and change datasource)
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Checked Items in ListBox lost after filtering

Post by jvierra »

You cannot lose data by filtering. You can only set or clear a filter. If you reassign a DataSource then you will clear all previous settings on the control to the current data source. If you want to keep the checks then you have to bind them to a binary field on the data source.
User avatar
Dead-Red02
Posts: 6
Last visit: Sat Feb 03, 2024 7:35 am
Answers: 1

Re: Checked Items in ListBox lost after filtering

Post by Dead-Red02 »

Ok i have solved it.

Thank's for your help, after reading your post, i stopped to set/reset back each time the datasource.

Errors :

In datatable, i set all time my id (integer) to [string] !
==>
  1.  $col1_result_all_Accessories = New-Object system.Data.DataColumn "Value", ([int])
I changed all the code in Itemcheck :
To keep values was selected before filter, i use global var : "$Script:Attribution_IT_Accessories_Checked_Items"
This var is set in global as follow : $Script:Attribution_IT_Accessories_Checked_Items = @("")
  1. $checkedlistbox2_ItemCheck = [System.Windows.Forms.ItemCheckEventHandler]{
  2.     if ($_.NewValue -eq 'Checked')
  3.     {
  4.                # If the new checked value is not present in $Script:Attribution_IT_Accessories_Checked_Items i add it
  5.                if ($checkedlistbox2.Items.Value[$_.Index] -notin $Script:Attribution_IT_Accessories_Checked_Items)
  6.         {
  7.             $Script:Attribution_IT_Accessories_Checked_Items += @($checkedlistbox2.Items.Value[$_.Index])      
  8.         }
  9.     }
  10.     else
  11.     {
  12.         $Script:Attribution_IT_Accessories_Checked_Items = @($Script:Attribution_IT_Accessories_Checked_Items | Where-Object { $_ -ne $checkedlistbox2.SelectedItem.Value })
  13.     }
  14.    
  15. }
My code in $combobox3.SelectedValue was good

I have change all code in combobox3_SelectionChangeCommitted
  1.     $Filter_Accessories_Provider_V = 'Provider =  ' + $combobox3.SelectedValue
  2.     if ($combobox4.SelectedValue)
  3.     {
  4.         $Filter_Accessories_Type_V = 'Type =  ' + $combobox4.SelectedValue
  5.         $datatable_result_all_Accessories.defaultview.rowfilter = "$Filter_Accessories_Provider_V AND $Filter_Accessories_Type_V"
  6.     }
  7.     else
  8.     {
  9.         $datatable_result_all_Accessories.defaultview.rowfilter = "$Filter_Accessories_Provider_V"
  10.     }
  11.     foreach($Item_Accessories in $Script:Attribution_IT_Accessories_Checked_Items)
  12.     {
  13.         for ($i_Accessories = 0; $i_Accessories -lt $checkedlistbox2.Items.Value.Count; $i_Accessories++)
  14.         {
  15.             if ($Item_Accessories -eq ($checkedlistbox2.Items.Value[$i_Accessories]))
  16.             {
  17.                 $checkedlistbox2.SetItemChecked($i_Accessories, $True)
  18.             }
  19.         }
  20.     }
To reset filter i changed the code too :
  1. $button4_Click = {
  2.     $checkedlistbox2.DataSource.defaultview.rowfilter = ""
  3.     foreach ($Item_Accessories in $Script:Attribution_IT_Accessories_Checked_Items)
  4.     {
  5.         for ($i_Accessories = 0; $i_Accessories -lt $checkedlistbox2.Items.Value.Count; $i_Accessories++)
  6.         {
  7.             if ($Item_Accessories -eq ($checkedlistbox2.Items.Value[$i_Accessories]))
  8.             {
  9.                 $checkedlistbox2.SetItemChecked($i_Accessories, $True)
  10.             }
  11.         }
  12.     }
  13.     $combobox4.DataSource = $null
  14.     $combobox3.DataSource = $null
  15. }
And now, all works fine !

I would like to say Thank's to Jvierra for his help and responses of MANY topics on this forum that have helped me on this problem and others. And second thank's to Sapien for this GREATEST software !
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Checked Items in ListBox lost after filtering

Post by jvierra »

Your issue is becoming ever vaguer and more confusing. Perhaps English is not your first language or maybe it is just typos.

A field in the DataSource for a checkbox must be a Boolean. The field must also be specified as a bound DataFieldName.

It is almost never useful to use "global" variables. The control is global to the form. any variable that needs to be maintained throughout a form life should be declared as a "script" scoped variable which makes it visible to the whole form.

Of course, if you use custom columns then you have access to other options.

I recommend starting with a simple form and a single DGV and a simple DataTable which can be hand built. Once you learn how to use these then the rest will become more obvious.
This topic is 2 years and 2 months old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked