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-ID: 561907

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

Ausgedruckt am: 25.11.2024 um 09:11 Uhr

143127
143127 29.03.2020 aktualisiert um 11:35:31 Uhr
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.
Bugger
Bugger 29.03.2020 um 12:12:48 Uhr
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.
143127
143127 29.03.2020 aktualisiert um 12:30:42 Uhr
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 ...
Bugger
Bugger 29.03.2020 um 13:25:31 Uhr
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
mayho33
mayho33 30.03.2020 um 16:51:53 Uhr
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!
TK1987
TK1987 30.03.2020 aktualisiert um 18:20:56 Uhr
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
Bugger
Bugger 30.03.2020 um 19:08:23 Uhr
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
TK1987
TK1987 30.03.2020 aktualisiert um 23:03:42 Uhr
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
Bugger
Bugger 31.03.2020 um 07:56:37 Uhr
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.
TK1987
TK1987 31.03.2020 aktualisiert um 09:38:08 Uhr
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.
Bugger
Bugger 31.03.2020 um 14:49:29 Uhr
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
TK1987
TK1987 31.03.2020 aktualisiert um 15:29:38 Uhr
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) "   
Bugger
Bugger 31.03.2020 aktualisiert um 19:32:43 Uhr
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?