combobox and valuemember

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.
Locked
User avatar
yves22
Posts: 17
Last visit: Tue Sep 13, 2022 1:21 am
Been upvoted: 1 time

combobox and valuemember

Post by yves22 »

Hi,

I used for a long time the function automatically added (Update-ComboBox) in a form when you create a combobox.
Since today I haven't have to used the "ValueMember" argument.

When I try to use it, it always retrieve the ValueMember of the last entry of the ComboBox.

Here below the code I used :
  1. $ListDoc = (Invoke-SqlQuery -Query "SELECT DOC_ID, DOC_APP, DOC_PATH FROM DOC ORDER BY DOC_APP" -ConnectionName $Database) | Select-Object DOC_ID, DOC_APP, DOC_PATH
  2.     Update-ComboBox -ComboBox $ComboBox_DeleteRow -Items "" -ValueMember ""
  3.     $ListDoc  | ForEach-Object {
  4.         $Display = ($_.DOC_APP) + " : " + ($_.DOC_PATH)
  5.         $Identifiant = $_.DOC_ID
  6.         Update-ComboBox -ComboBox $ComboBox_DeleteRow -Items $Display -DisplayMember $Display -ValueMember $Identifiant -Append
  7.     }
The value of "$ComboBox_DeleteRow.ValueMember" is alway equal to 8.
8 is the value of "$_.DOC_ID" last entry of the combobox "ComboBox_DeleteRow".

Thanks for your anwser,
Sincerly yours.
jvierra
Posts: 15286
Last visit: Mon Sep 26, 2022 6:41 pm
Answers: 26
Has voted: 4 times
Been upvoted: 27 times

Re: combobox and valuemember

Post by jvierra »

"ValueMember" takes a string constant that names the member you want to be set in the "Value" property of the ComboBox.

You cannot gather this string by enumerating a collection.

A ComboBox should be loaded by just adding the array to the CB.

An easier method is to just assign the table to the CB.

Here is all you need with a DataTable.
  1. $ListDoc = Invoke-SqlQuery -Query 'SELECT DOC_ID, DOC_APP, DOC_PATH FROM DOC ORDER BY DOC_APP' -ConnectionName $Database
  2. ComboBox_DeleteRow.DataSource = $ListDoc
  3. ComboBox_DeleteRow.DisplayMember = 'DOC_APP'
  4. ComboBox_DeleteRow.ValueMember = 'DOC_ID'
User avatar
yves22
Posts: 17
Last visit: Tue Sep 13, 2022 1:21 am
Been upvoted: 1 time

Re: combobox and valuemember

Post by yves22 »

Hi,

I found another way to dislay the "ValueMember" attribut on your forum.
The result of the query is a hashtable.
I must create a System.Data.DataTable object.

Below the code I used :
  1. $ComboBox_DelRowItem = (Invoke-SqlQuery -Query "SELECT DOC_ID, DOC_APP, DOC_PATH FROM DOC ORDER BY DOC_APP, DOC_PATH" -ConnectionName $Database) | Select-Object DOC_ID, DOC_APP, DOC_PATH
  2.     $DataTableDelRow = New-Object System.Data.DataTable
  3.     $DataTableDelRow.Columns.Add('DISPLAY')
  4.     $DataTableDelRow.Columns.Add('ID')
  5.     $DataTableDelRow.Rows.Add('', '')
  6.     $ComboBox_DelRowItem | ForEach-Object {
  7.         $Display = ($_.DOC_APP) + " : " + ($_.DOC_PATH)
  8.         $Identifiant = $_.DOC_ID
  9.         $DataTableDelRow.Rows.Add($Display, $Identifiant)
  10.     }
  11.     $ComboBox_DeleteRow.DataSource = $DataTableDelRow
  12.     $ComboBox_DeleteRow.DisplayMember = 'DISPLAY'
I retrieve the combobox valuemember attribut by :
$ComboBox_DeleteRow.$ComboBox_DeleteRow.SelectedItem.ID

Thanks for your help
Sincerly yours
jvierra
Posts: 15286
Last visit: Mon Sep 26, 2022 6:41 pm
Answers: 26
Has voted: 4 times
Been upvoted: 27 times

Re: combobox and valuemember

Post by jvierra »

You are absolutely wrong about having to create a table object. The SQL query returns a datatable and the CB is designed to work with DataTable objects. Hash tables are not really usable with controls as a datasource. The Update-ComboBox CmdLet internally turns a hash into a DataTable.

You cannot get good functionality in a CB using your method.

I have been using the correct method in all Windows data-enabled controls for two decades. Take my word for it, you are just boxing yourself into a corner.

You do not need to use Select-Object since the SQL returns those fields in a DT and using "Select-Object" just destroys the DataTable.

I recommend taking some time to learn how WinForms and WinForms controls work and how they are designed to enable and simplify coding with data objects. You might also learn how to use SQL to retrieve data in the form you need it to be used in. These things will simplify your code and it will also reduce the amount of code you write by more than a factor of ten.

Good luck.
Locked