bugger
Goto Top

Powershell ComboBox neben Dynamischer Checkbox

Hallo,

wie kann ich bei einer Reihe von dynamisch erstellten Checkboxen eine ComboBox an eine bestimmte Checkbox binden? Sodass die ComboBox z.B. immer 15 Pixel rechs neben Checkbox Test3 steht?

Beispielcode:
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null  
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null  

$form1 = New-Object System.Windows.Forms.Form
$button1 = New-Object System.Windows.Forms.Button
$listBox1 = New-Object System.Windows.Forms.ListBox
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState


#----------------------------------------------
#Generated Event Script Blocks
#----------------------------------------------

$handler_button1_Click= 
{
    # Iterate over the checkboxes, one by one
    if ( $form1.Controls['Checkbox2'].Checked -eq $true ){write-host "test2"}  
    if ( $form1.Controls['Checkbox5'].Checked -eq $true ){write-host "test5"}  
    if (($form1.Controls | ? Text -eq 'Test1').Checked){  
     write-host "test1"  
}
}

$OnLoadForm_StateCorrection=
{#Correct the initial state of the form to prevent the .Net maximized form issue
    $form1.WindowState = $InitialFormWindowState
}

#----------------------------------------------
#region Generated Form Code
$form1.Text = "Primal Form"  
$form1.Name = "form1"  
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 450
$System_Drawing_Size.Height = 236
$form1.ClientSize = $System_Drawing_Size


# Keep track of number of checkboxes
$CheckBoxCounter = 1

$CheckBoxLabels=@(
"Test1"  
"Test2"  
"Test3"  
"Test4"  
)

# When we create a new textbox, we add it to an array for easy reference later
$CheckBoxes = foreach($Label in $CheckBoxLabels) {
    $CheckBox = New-Object System.Windows.Forms.CheckBox        
    $CheckBox.UseVisualStyleBackColor = $True
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = 104
    $System_Drawing_Size.Height = 24
    $CheckBox.Size = $System_Drawing_Size
    $CheckBox.TabIndex = 2

    # Assign text based on the input
    $CheckBox.Text = $Label

    $System_Drawing_Point = New-Object System.Drawing.Point
    $System_Drawing_Point.X = 25
    # Make sure to vertically space them dynamically, counter comes in handy
    $System_Drawing_Point.Y = 15 + (($CheckBoxCounter - 1) * 20)
    $CheckBox.Location = $System_Drawing_Point
    $CheckBox.DataBindings.DefaultDataSourceUpdateMode = 0

    # Give it a unique name based on our counter
    $CheckBox.Name = "CheckBox$CheckBoxCounter"  

    # Add it to the form
    $form1.Controls.Add($CheckBox)
    # return object ref to array
    $CheckBox
    # increment our counter
    $CheckBoxCounter++
}

$ComboBoxLogPicker               = New-Object system.Windows.Forms.ComboBox
$ComboBoxLogPicker.width         = 100
$ComboBoxLogPicker.height        = 8
$System_Drawing_Point.X = 27
$System_Drawing_Point.Y = 15 + (($CheckBoxCounter - 1) * 21)
$ComboBoxLogPicker.location      = $System_Drawing_Point
$ComboBoxLogPicker.Font          = 'Microsoft Sans Serif,8'  
$LogPickerOptions                = "1", "2", "3", "4"  
foreach($Picker in $LogPickerOptions){
    $ComboBoxLogPicker.Items.Add($Picker)
}
$form1.Controls.Add($ComboBoxLogPicker)

$button1.TabIndex = 4
$button1.Name = "button1"  
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 75
$System_Drawing_Size.Height = 23
$button1.Size = $System_Drawing_Size
$button1.UseVisualStyleBackColor = $True

$button1.Text = "Run Script"  

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 27
$System_Drawing_Point.Y = 15 + (($CheckBoxCounter - 1) * 30)
$button1.Location = $System_Drawing_Point
$button1.DataBindings.DefaultDataSourceUpdateMode = 0
$button1.add_Click($handler_button1_Click)

$form1.Controls.Add($button1)

$listBox1.FormattingEnabled = $True
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 301
$System_Drawing_Size.Height = 212
$listBox1.Size = $System_Drawing_Size
$listBox1.DataBindings.DefaultDataSourceUpdateMode = 0
$listBox1.Name = "listBox1"  
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 137
$System_Drawing_Point.Y = 13
$listBox1.Location = $System_Drawing_Point
$listBox1.TabIndex = 3

$form1.Controls.Add($listBox1)




#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($OnLoadForm_StateCorrection)
#Show the Form
$form1.ShowDialog()| Out-Null

Danke und Gruß

Content-Key: 561907

Url: https://administrator.de/contentid/561907

Printed on: April 27, 2024 at 03:04 o'clock

Mitglied: 143127
143127 Mar 29, 2020 updated at 09:35:31 (UTC)
Goto Top
Naja warum packst du die Erstellung der Combobox denn nicht einfach mit in die Schleife über die Checkboxen (Zeile 51)?? Da brauchst du nur noch die X-Koordinate für die Combobox anpassen (Abstand) und feddich ist die Suppe ... Manchmal frage ich mich wo die Leute ihren Kopf abstellen face-smile.
Member: Bugger
Bugger Mar 29, 2020 at 10:12:48 (UTC)
Goto Top
Sorry, verstehe ich nicht face-smile

Es geht nicht darum das die Combobox rechts neben den Checkboxen ist sondern z.B. immer neben Checkbox Test3. Zukünftig will ich noch eine weitere Combobox haben, die dann z.B. immer rechts neben der Checkbox Test5 liegt.
Mitglied: 143127
143127 Mar 29, 2020 updated at 10:30:42 (UTC)
Goto Top
Zitat von @Bugger:

Sorry, verstehe ich nicht face-smile

Es geht nicht darum das die Combobox rechts neben den Checkboxen ist sondern z.B. immer neben Checkbox Test3.
Alle übereinander oder wie?
Zukünftig will ich noch eine weitere Combobox haben, die dann z.B. immer rechts neben der Checkbox Test5 liegt.
Dann lege sie doch an der richtigen Koordinate an, die Koordinaten hast du ja bereits wenn du die Checkbox erstellst. Dann einfach den Abstand nach Rechts vergrößern fertig, verstehe dein Problem ehrlich gesagt nicht wirklich ...
Member: Bugger
Bugger Mar 29, 2020 at 11:25:31 (UTC)
Goto Top
Zitat von @143127:
Alle übereinander oder wie?
Ja, teilweise, habe mal ein Bild angehangen was ich meine. Und da die Checkboxen dynamisch erstellt werden und eventuell mal eine hinzukommt oder entfernt wird, soll die Combobox an die Checkbox gekoppelt sein, damit dies ebenfalls dynamisch ist.
1
Member: mayho33
mayho33 Mar 30, 2020 at 14:51:53 (UTC)
Goto Top
Hi,

Wenn ich dich richtig verstehe willst du zur Laufzeit Comboboxen hinzufügen?

Erstelle einmal ein StackPanel. In diesem kannst du alle Elemente (je nach Setting) untereinander reihen.

Im StackPanel erstellt du ein DockPanel. In diesem werden alle Elemente automatisch horizontal angeordnet.

Dem DockPanel gibst du einen x:Name

Nun kannst du via x:Name und "add" zur Laufzeit im Code behind weitere Elemente hinzufügen.

Wie genau das geht suche dir bitte in den Microsoft.Docs.

Grüße!
Member: TK1987
TK1987 Mar 30, 2020 updated at 16:20:56 (UTC)
Goto Top
Moin,

Zitat von @Bugger:
Es geht nicht darum das die Combobox rechts neben den Checkboxen ist sondern z.B. immer neben Checkbox Test3. Zukünftig will ich noch eine weitere Combobox haben, die dann z.B. immer rechts neben der Checkbox Test5 liegt.
Bastel dir doch eine Funktion, die dir die Checkbox und die Combobox direkt daneben anlegt.

Z. B. so:
function checkCombo() {
	Param(
		[int]$x=25,
		[int]$y
		)
	
	$Checkbox=New-Object System.Windows.Forms.Checkbox -Property @{
		Location="$x,$y"  
		Checked=$true
		}
	$x+=15
	$Combobox=New-Object System.Windows.Forms.Combobox -Property @{
		Location="$x,$y"  
		}
		
	return $Checkbox,$Combobox
	}
so brauchst du nur noch die Funktion aufrufen und ihr den entsprechenden y-wert für die Location zu übergeben. Beispiel:
$Test3,$Combo3=checkCombo -y 50
und schon wird in dem Fall eine Checkbox in $Test3 und die Combobox direkt daneben in $Combo3 gespeichert. Parameter kannst du auch noch nach belieben ergänzen.

Gruß Thomas
Member: Bugger
Bugger Mar 30, 2020 at 17:08:23 (UTC)
Goto Top
@mayho33
Das sieht interessant aus, gucke ich mir mal genauer an.

@thomas
Das ist auch nicht schlecht, scheint aber nicht wirklich Bezug auf den Dynamischen Teil der die Checkboxen erstellt zu legen, oder?


Ich habe es mittlerweile so gelöst:

$ComboBoxLogPicker               = New-Object system.Windows.Forms.ComboBox
$ComboBoxLogPicker.DropDownStyle = "DropDownList"  
$ComboBoxLogPicker.width         = 100
$ComboBoxLogPicker.height        = 8
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 41
$System_Drawing_Point.Y = 15 + 0*20
$ComboBoxLogPicker.location      = $System_Drawing_Point
$ComboBoxLogPicker.Font          = 'Microsoft Sans Serif,8'  
$ComboBoxLogPicker.Items.AddRange(@('1', '2', '3', '4', '5', '6'))  
$ComboBoxLogPicker.SelectedIndex = 0
$form1.Controls.Add($ComboBoxLogPicker)

Wichtig ist das der Block über der Schleife liegt da ansonsten der Text der Checkboxen die Combobox überdeckt.
Bei System_Drawing_Point.Y ersetze ich die 0 mit der Nummer der Checkbox. Das ist allerdings auch nicht dynamisch und ich muss die Zahl anpassen wenn sich etwas verschiebt aber zumindest ist es so wie ich mir das vorgestellt habe. Vielleicht hat ja noch jemand eine Idee zum Dynamischen teil face-smile Aber schon mal vielen Dank für die Antworten face-smile
Member: TK1987
TK1987 Mar 30, 2020 updated at 21:03:42 (UTC)
Goto Top
Zitat von @Bugger:
@thomas
Das ist auch nicht schlecht, scheint aber nicht wirklich Bezug auf den Dynamischen Teil der die Checkboxen erstellt zu legen, oder?
Natürlich kann man das für den dynamischen Teil nutzen, der die Checkboxen erstellt - kommt immer drauf an, was man daraus macht 😉.
Wichtig ist das der Block über der Schleife liegt da ansonsten der Text der Checkboxen die Combobox überdeckt.
Warum gibst du den Checkboxen, bei denen eine Combobox daneben soll denn überhaupt einen Text, wenn dieser ohnehin nicht sichtbar ist?

Wenn ich dass richtig sehe, willst du immer abwechselnd eine Checkbox mit Text und eine Checkbox mit Combobox daneben, richtig?
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$Form1=New-Object System.Windows.Forms.Form -Property @{
  Text="Primal Form"  
  Autosize=$true
  Padding="25,25,25,25"  
  }

# Startwert Y-Location
$y=40
  
# Tabindex
$Tab=1
  
For ($i=1;$i -lt 6;$i+=2) {
  # Checkbox mit Text
  [Array]$Checkboxes+=New-Object System.Windows.Forms.Checkbox -Property @{
    Text="Test $i"  
    Name="Test $i"  
    Location="25,$y"  
    UseVisualStyleBackColor = $True
    Size="104,24"  
    Tabindex=$Tab
    }
	
  $y+=25
  $Tab++
  
  # Checkbox mit Combobox
  [Array]$Checkboxes+=New-Object System.Windows.Forms.Checkbox -Property @{
    Name="Test $($i+1)"  
    Location="25,$y"  
    UseVisualStyleBackColor = $True
    Size="15,24"  
    Tabindex=$Tab
    }
	
  $Tab++
  
  [Array]$Comboboxes+=New-Object System.Windows.Forms.Combobox -Property @{
    Location="40,$y"  
    Size="100,24"  
    Font='Microsoft Sans Serif,8'  
    Tabindex=$Tab
    }
  
  # Items Combobox
  $Comboboxes[-1].Items.AddRange($(1..4))
  $Comboboxes[-1].SelectedIndex=0
	
  $y+=25
  $Tab++
  
  } # Ende For-Schleife
  
$y+=30

$Button1=New-Object System.Windows.Forms.Button -Property @{
  Text="Run Script"  
  Location="25,$y"  
  Size="75,23"  
  }

$Button1.Add_Click({
	$Checkboxes | ? {$_.Checked} | % {
		write-host $_.Name
		}
	})

$Form1.Controls.AddRange($Comboboxes)
$Form1.Controls.AddRange($Checkboxes)
$Form1.Controls.Add($Button1)

[void]$Form1.ShowDialog()


output

Wenn du mehr Elemente willst, einfach in der For-Schleife den 2. Wert (also den Wert hinter $i -lt) um 2 erhöhen - und das Fenster wächst durch Autosize=$true auch gleich mit.

Gruß Thomas
Member: Bugger
Bugger Mar 31, 2020 at 05:56:37 (UTC)
Goto Top
Zitat von @TK1987:
Warum gibst du den Checkboxen, bei denen eine Combobox daneben soll denn überhaupt einen Text, wenn dieser ohnehin nicht sichtbar ist?
Der Name wird ja automatisch erstellt durch CheckBoxLabel und bei den Anderen Boxen brauche ich den Namen ja auch face-smile

Wenn ich dass richtig sehe, willst du immer abwechselnd eine Checkbox mit Text und eine Checkbox mit Combobox daneben, richtig?
Das war jetzt nur in dem Beispiel so, es kann auch mal zwei Comboboxen hintereinander sein.
Member: TK1987
TK1987 Mar 31, 2020 updated at 07:38:08 (UTC)
Goto Top
Zitat von @Bugger:
Der Name wird ja automatisch erstellt durch CheckBoxLabel und bei den Anderen Boxen brauche ich den Namen ja auch face-smile
Aber bei denen mit der Combobox brauchst du ihn eben nicht und kannst ihn daher getrost weglassen.
BTW:
Wichtig ist das der Block über der Schleife liegt da ansonsten der Text der Checkboxen die Combobox überdeckt.
Das ist so nicht richtig. Wo der Block liegt spielt überhaupt keine Rolle.
Entscheidend dafür, was im Hintergrund und was im Vordergrund liegt, ist nur die Reihenfolge, in der die Elemente zur Form hinzugefügt werden.

Das war jetzt nur in dem Beispiel so, es kann auch mal zwei Comboboxen hintereinander sein.
Dann überleg dir doch erst mal vorher, was du wann und wie genau haben willst.
Du musst dir schon irgendeine Regel einfallen lassen, in welchem Fall eine Combobox angelegt werden soll und in welchem eben nicht, sonst ist der ganze dynamik-Gedanke doch ohnehin hinfällig.
Member: Bugger
Bugger Mar 31, 2020 at 12:49:29 (UTC)
Goto Top
Zitat von @TK1987:
Dann überleg dir doch erst mal vorher, was du wann und wie genau haben willst.

Ich hatte gehofft, dass man bei der Zeile $System_Drawing_Point.Y = 15 + 0*20 irgnedwie die 0 mit dem Namen der Checkbox ersetzen kann. Da dass aber wohl schwieriger ist als gedacht bleibe ich halt bei den Nummern.
Trotzdem vielen Dank für die Vorschläge, die werden mir bestimmt später nochmal nützlich sein face-smile
Member: TK1987
TK1987 Mar 31, 2020 updated at 13:29:38 (UTC)
Goto Top
Zitat von @Bugger:
Ich hatte gehofft, dass man bei der Zeile $System_Drawing_Point.Y = 15 + 0*20 irgnedwie die 0 mit dem Namen der Checkbox ersetzen kann.
Natürlich geht das grundsätzlich. Dennoch musst du doch irgendeine Regel haben, wann die Combobox überhaupt angelegt wird. Es macht ja keinen Sinn, die Checkboxen dynamisch erstellen zu lassen, die Comboboxen aber dann statisch zu erstellen.

Davon mal abgesehen: Ich weiß zwar, dass das mit dem System.Drawing.Point in vielen Anleitungen so auftaucht... keine Ahnung ob das in früheren Version mal erforderlich war, oder immer nur überflüssiger Weise abgeschrieben wurde - aber ich würde die Werte immer direkt setzen, alleine schon um das Ganze übersichtlicher zu gestalten.
$Object.Location="20,40" # "X-Wert, Y-Wert"  
Das selbe mit Size
$Object.Size="100,26" # "Breite, Höhe"  
bzw. wenn du den Wert noch ausrechnen muss in $(), also z.B.:
$Object.Location="25 , $(15+2*20) "   
Member: Bugger
Bugger Mar 31, 2020 updated at 17:32:43 (UTC)
Goto Top
Die Comboboxen muss ich tatsächlich statisch erstellen, da es da kein Muster gibt wann es eine Combobox sein sollte und wann nicht, deshalb wollte ich zumindest die Location dynamisch haben damit sich die Combobox entsprechend anpasst.

Die Sache mit dem System.Drawing.Point habe ich wirklich ganz viel gesehen, habe ich gleich mal umgebaut, Danke face-smile
Sowas wie $Object.Location = New-Object System.Drawing.Size(10,20) ist wahrscheinlich genauso überflüssig?