Disable specific items in a CheckedListBox

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 3 years and 2 weeks 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
hopkinsnd
Posts: 9
Last visit: Thu Apr 07, 2022 2:41 pm

Disable specific items in a CheckedListBox

Post by hopkinsnd »

I'm populating a CheckedListBox and I am trying to disable specific items. I found a few examples, but nothing specific to PowerShell (WinForms) seems to work. The attached screenshot is an example of a CheckedListBox with some items disabled that I found on another board specific to C#.
  1.     $services = Get-Service | select Name
  2.     $checkedlistbox1.Items.Clear()
  3.     foreach ($service in $services)
  4.     {
  5.         If ($service.Name -eq "ALG")
  6.         {
  7.             $checkedlistbox1.Items.Add($($service).Name, $true)
  8.         }
  9.         Else
  10.         {
  11.             $checkedlistbox1.Items.Add($($service).Name, $false)
  12.         }
  13.     }
Attachments
CheckedListBox - Disabled Items.PNG
CheckedListBox - Disabled Items.PNG (4.62 KiB) Viewed 3556 times
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Disable specific items in a CheckedListBox

Post by jvierra »

It appears that ALG is not the name of any service. Use the debugger to check the code.
It also seems that there is other code that may be overwriting your code. You may have scope issues or issues with code sequence. The code posted must be inside an event or structured correctly.
User avatar
hopkinsnd
Posts: 9
Last visit: Thu Apr 07, 2022 2:41 pm

Re: Disable specific items in a CheckedListBox

Post by hopkinsnd »

ALG is a service on my computer. You can change the service you want to have show in the list as disabled to any service you want. You can try WinRM. That service should be on every Windows computer.

The goal is when WinRM shows up in the CheckedListBox, for that item to be automatically checked and to have the control disabled so it cannot be unchecked.
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Disable specific items in a CheckedListBox

Post by jvierra »

I still do not understand what your issue is or what code is being used. The code posted and the image do not match. The image says other code is executing.

The code must be in an event and it must be in the correct kind of event. You cannot just type code into anyplace in a form.
User avatar
hopkinsnd
Posts: 9
Last visit: Thu Apr 07, 2022 2:41 pm

Re: Disable specific items in a CheckedListBox

Post by hopkinsnd »

The attached picture is an example of what I wanted the checkedlistbox to look like (with some items disabled).

I've been able to solve this on my own. Here are the steps and sample code I used...

First I created a button to get all the services on my computer. I am using the service "ALG" as an example service that I want to be checked and greyed out in the checkedlistbox. Within the first foreach loop I'm adding the services to the checkedlistbox. If the servie name is "ALG", I'm checking the box by default. I'm also adding the service name to an array ($arrExistingApprovals, which initialized when the form loaded. Completing the first foreach loop adds the rest of the services to the checkedlistbox without the checkbox checked.

The second foreach loop goes through each service that was added to the $arrExistingApprovals array and sets the checkedstate to 'Indeterminate' This causes the text to be grayed out.
  1. $buttonGetServices_Click={
  2.     #TODO: Place custom script here
  3.     $services = Get-Service | select Name
  4.     $checkedlistbox1.Items.Clear()
  5.     foreach ($service in $services)
  6.     {
  7.         If ($service.Name -eq "ALG")
  8.         {
  9.             $checkedlistbox1.Items.Add($($service).Name, $true)
  10.             $global:arrExistingApprovals += $service.Name
  11.         }
  12.         Else
  13.         {
  14.             $checkedlistbox1.Items.Add($($service).Name, $false)
  15.         }
  16.     }
  17.    
  18.     foreach ($item in $global:arrExistingApprovals)
  19.     {
  20.         $checkedlistbox1.SetItemCheckState($checkedlistbox1.Items.IndexOf($item), [System.Windows.Forms.CheckState]::Indeterminate)
  21.     }
  22. }
Next I wanted to make sure that the checkbox couldn't be unchecked. I found that you cannot natively disable that for an item within a checkedlistbox. Here's my workaround. When the selected index is changed if the arrExistingItems array contains the service that was selected, this action will recheck the box and set it to Indeterminate.
  1. $checkedlistbox1_SelectedIndexChanged={
  2.     #TODO: Place custom script here
  3.     If ($global:arrExistingApprovals -contains $checkedlistbox1.SelectedItem)
  4.     {
  5.         $checkedlistbox1.SetItemCheckState($checkedlistbox1.SelectedIndex, [System.Windows.Forms.CheckState]::Indeterminate)
  6.     }
  7. }
Finally, I created a ContextMenuStrip with one item. The goal for the ContextMenuStrip is to show a menu only if the checklistbox item is in the Indeterminate state.
  1. $contextmenustrip1_Opening=[System.ComponentModel.CancelEventHandler]{
  2. #Event Argument: $_ = [System.ComponentModel.CancelEventArgs]
  3.     #TODO: Place custom script here
  4.     If ($global:arrExistingApprovals -contains $checkedlistbox1.SelectedItem)
  5.     {
  6.         Write-Host "Menu will be shown"
  7.     }
  8.     Else
  9.     {
  10.         $_.Cancel = $true
  11.     }
  12. }
I know this is a lot of code to just show some services and a context menu, but the goal for this code is to integrate the workflow into a custom Powershell form for presenting ConfigMgr (SCCM) applications that require approval. The checkedlistbox will contain all the applications available for a specific endpoint. For applications that have an existing approval, the application will be grayed out. The context menu item will be available for this item to right-click and choose "Remove Approval | Uninstall Application." This action will invoke a WMI call to the SCCM server to deny the application for that endpoint, which creates an uninstall action on the endpoint. For other available applications checking the box/boxes and selecting Next will invoke a WMI call to the SCCM server, creating an approval request. This will install the application on the endpoint.
User avatar
hopkinsnd
Posts: 9
Last visit: Thu Apr 07, 2022 2:41 pm

Re: Disable specific items in a CheckedListBox

Post by hopkinsnd »

Forgot to add the screen shots of the SCCM form and the original sample form.
Attachments
Install Confirmation.PNG
Install Confirmation.PNG (13.08 KiB) Viewed 3470 times
Install Sent.PNG
Install Sent.PNG (15.38 KiB) Viewed 3470 times
CheckedListBoxTest.psf
(43.6 KiB) Downloaded 145 times
User avatar
hopkinsnd
Posts: 9
Last visit: Thu Apr 07, 2022 2:41 pm

Re: Disable specific items in a CheckedListBox

Post by hopkinsnd »

Some of the attachments didn't attach again. :-(
Attachments
Available Applications.PNG
Available Applications.PNG (13.66 KiB) Viewed 3470 times
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Disable specific items in a CheckedListBox

Post by jvierra »

I still cannot understand your issue. YOu say you want to check only "ALG" then show other things with no ALG in the list.

ALG is "Application Layer Gateway". It is not in your list.
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Disable specific items in a CheckedListBox

Post by jvierra »

To best control data in a ListBox it is better to use a DataTable and bind the property. The DataTable has more options.

From your code I see that you seem to have some issues with PS and how it works. This is likley part of the issue.
EXAMPLE:

This: $checkedlistbox1.Items.Add($service.Name, $true)
Should be: $checkedlistbox1.Items.Add($service.Name, $true)

Using $() is only for forcing subexpression resolution. It can create issues when used arbitrarily. In the code you posted it is never necessary.

By using a DataTable you can store and summarize all requirements in a structure that can set the ListBox and checks in a completely abstract manner so the display is decoupled from you rules. Process the table then bind which will allow simpler code and code that is easier to debug.
This topic is 3 years and 2 weeks 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