markus2016
Goto Top

Powershell: ScrollBar in ListBox definieren

Hallo zusammen,

benötige mal wieder Unterstüzung. face-smile

Ich erzeuge CheckBoxen in einem Array.
Aufgrund deren Anzahl benötige ich einen Scrollbar, welchen ich über eine ListBox hinzufüge.

Mein Problem, ich habe keine Ahnung, wie ich den Input für die Scrollbar richtig definieren kann/ soll?

Wenn ich dies über "Items.AddRange" mache, funktioniert die Scrollbar. Ist aber nicht wirklich toll mit den dargestellten Zahlen. face-sad

listbox

$Global:Feature = @(Get-WindowsOptionalFeature -Path "$Global:Projekt\Mount" | Select FeatureName, State)  

$Global:FeatureName = @($Global:Feature | Where-Object {$_} | ForEach-Object {$_} | Sort-Object FeatureName | Select-Object)
$Global:FeatureCheckbox = @()  

$Global:CheckboxBox = New-Object System.Windows.Forms.ListBox
$Global:CheckboxBox.Location = New-Object System.Drawing.Point(350,70) 
$Global:CheckboxBox.Size = New-Object System.Drawing.Size(590,420)
$Global:CheckboxBox.DataBindings.DefaultDataSourceUpdateMode = 0
$Global:CheckboxBox.ScrollAlwaysVisible = $true
$Global:CheckboxBox.BorderStyle = "none"  
$Global:CheckboxBox.Items.AddRange(1..200)   
$Global:Window.Controls.Add($Global:CheckboxBox)

$i = 0
ForEach ($_ in $Global:FeatureName ) {

$Global:Feature = New-Object System.Windows.Forms.Checkbox
$Global:Feature.Text = $_.FeatureName
$Global:Feature.Name = $_.FeatureName
$Global:Feature.Tag = $_.State
$Global:Feature.DataBindings.DefaultDataSourceUpdateMode = 0
$Global:FeatureCheckbox += @($Global:Feature)
$Global:CheckboxBox.Controls.Add($Global:Feature)

$Global:FeatureState = New-Object System.Windows.Forms.Label
$Global:FeatureState.Text = $_.State
$Global:FeatureState.Name = $_.FeatureName
$Global:FeatureState.DataBindings.DefaultDataSourceUpdateMode = 0
$Global:CheckboxBox.Controls.Add($Global:FeatureState)
    
$i++
$Y = $i * 20

$Global:Feature.Location = New-Object System.Drawing.Size(20,($Y-10)) 
$Global:Feature.Size = New-Object System.Drawing.Size(280,20)

$Global:FeatureState.Location = New-Object System.Drawing.Size(300,($Y-10)) 
$Global:FeatureState.Size = New-Object System.Drawing.Size(180,20)
}

Schöne Grüße

Markus 2016

Content-Key: 325228

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

Printed on: April 19, 2024 at 23:04 o'clock

Member: emeriks
Solution emeriks Jan 01, 2017 at 19:22:11 (UTC)
Goto Top
Hi,
warum nimmst Du nicht gleich eine CheckedListBox?

E.
Member: Markus2016
Markus2016 Jan 01, 2017 at 19:50:25 (UTC)
Goto Top
Hallo emeriks,

eine CheckedListBox verwende ich nicht, da hiermit das Form.Label mit dem State der Features nach meinem Wissen nicht so eingebunden werden kann, dass ich später nach Enable / Disable in der GUI filtern kann.

Trotzdem Danke.

Schöne Grüße

Markus2016
Mitglied: 131381
131381 Jan 01, 2017 updated at 20:23:04 (UTC)
Goto Top
Zitat von @Markus2016:
eine CheckedListBox verwende ich nicht
@emeriks hat aber recht, das was eine Checkbox kann, kann auch eine checked listbox.
So wie du das oben machst ist das Grüzze, sorry aber das macht kein vernünftiger Programmierer.
, da hiermit das Form.Label mit dem State der Features nach meinem Wissen nicht so eingebunden werden kann, dass ich später nach Enable / Disable in der GUI filtern kann.
Glaube keiner versteht hier was du mit dem Kauderwelsch meinst.
Und natürlich kannst du die checked listbox nach enabled/disabled filtern, dafür gibt es sogar eine eigene Eigenschaft namens Checkeditems, wäre ja sinnlos wenn sowas nicht möglich wäre.
Ebenso kannt du das Items-Array dieser per Where-Objekt filtern!
Ich sehe hier kein Problem.

Du solltest dich vielleicht erst mal grundlegend mit Windows Forms-Elementen in Visual Studio auseinandersetzen, denn damit lernst du die Controls und Ihre Eigenschaften wesentlich besser kennen als wenn du nur mit der Powershell oder irgendeinem klicki bunti editor hantierst der einem nicht alle Möglichkeiten auf den ersten Blick zeigt.

Ich würde sowas per Datatable machen und in der GUI ein Control mit der Datatable per Source-Eigenschaft verknüpfen.
Hat den Vorteil das GUI und Daten jeweils verknüpft sind und beliebig viele Daten zu den Items hinterlegt werden können und alles immer synchron ist.

Gruß mik
Member: Markus2016
Markus2016 Jan 01, 2017 at 21:04:34 (UTC)
Goto Top
Hallo mikrotik,

wiedermal vielen lieben Dank für Deine Hilfe.

Ich sollte / werde mich nochmal mit der CheckListBox auseinandersetzen.

Sorry, hatte echt etwas unglücklich formuliert was ich machen möchte.

Du hast recht, mein größtes Problem ist immer, dass ich keinen Überblick über die verschiedenen Möglichkeiten habe.
Ich verwende ausschließlich Powershell.
Der Tipp mit Visual Studio macht wohl Sinn. face-smile

Schöne Grüße

Markus2016
Member: Markus2016
Markus2016 Jan 02, 2017 at 14:28:53 (UTC)
Goto Top
Hallo zusammen,

ich brauche noch einen Tipp.

In möchte in der CheckedListBox, wie in dem Bild oben, den Status der Features mit anzeigen.
Wie kann ich die CheckedListBox um die Anzeige des "$_.State" erweitern?

$Global:Feature = @(Get-WindowsOptionalFeature -Path "$Global:Projekt\Mount" | Select FeatureName, State)  

$Global:FeatureName = @($Global:Feature | Where-Object {$_} | ForEach-Object {$_} | Sort-Object FeatureName | Select-Object)
$Global:FeatureCheckbox = @()  

$i = 0
ForEach ($_ in $Global:FeatureName ) {

$Global:FeatureBox = New-Object System.Windows.Forms.CheckedListBox
$Global:FeatureBox.Text = $_.FeatureName
$Global:FeatureBox.Name = $_.FeatureName
$Global:FeatureBox.Tag = $_.State
$Global:FeatureBox.DataSource = $Global:Feature.FeatureName
$Global:FeatureBox.DataBindings.DefaultDataSourceUpdateMode = 0
$Global:FeatureBox.BorderStyle = "none"  
$Global:FeatureCheckbox += @($Global:FeatureBox)
$Global:Window.Controls.Add($Global:FeatureBox)
    
$i++

$Global:FeatureBox.Location = New-Object System.Drawing.Size(350,70) 
$Global:FeatureBox.Size = New-Object System.Drawing.Size(590,420)

}

@ mikrotik, mit dem Tipp Datatable und Visual Studio werde ich mich, sobald ich das hinbekommen habe, beschäftigen.

Vielen Dank.

Schöne Grüße

Markus2016
Mitglied: 131381
Solution 131381 Jan 02, 2017 updated at 14:48:51 (UTC)
Goto Top
In dem Fall nimmst du besser ein ListView- oder DataGridView-Control.

Hier ein Beispiel für ein ListView-Control:
function GenerateForm {

#region Import the Assemblies
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null  
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null  
#endregion

#region Generated Form Objects
$form1 = New-Object System.Windows.Forms.Form
$listview = New-Object System.Windows.Forms.ListView
$colName = New-Object System.Windows.Forms.ColumnHeader
$colState = New-Object System.Windows.Forms.ColumnHeader
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
#endregion Generated Form Objects

$handler_form1_Load= 
{
    1..10 | %{
        $item = $listview.Items.Add("Programm $_")  
        $item.SubItems.Add((@('Enabled','Disabled') | Get-Random))  
    }
}

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

#----------------------------------------------
#region Generated Form Code
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 282
$System_Drawing_Size.Width = 383
$form1.ClientSize = $System_Drawing_Size
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$form1.MaximizeBox = $False
$form1.MinimizeBox = $False
$form1.Name = "form1"  
$form1.Text = "ListView"  
$form1.add_Load($handler_form1_Load)

$listview.Anchor = 15

$listview.CheckBoxes = $True
$listview.Columns.Add($colName)|Out-Null
$listview.Columns.Add($colState)|Out-Null
$listview.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 12
$listview.Location = $System_Drawing_Point
$listview.MultiSelect = $False
$listview.Name = "listview"  
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 258
$System_Drawing_Size.Width = 359
$listview.Size = $System_Drawing_Size
$listview.TabIndex = 1
$listview.UseCompatibleStateImageBehavior = $False
$listview.View = 1
$listView.FullRowSelect = $true

$form1.Controls.Add($listview)

$colName.Name = "colName"  
$colName.Text = "Name"  
$colName.Width = 173

$colState.Name = "colState"  
$colState.Text = "State"  
$colState.Width = 110

#endregion Generated Form Code

#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

} #End Function

GenerateForm
Member: Markus2016
Markus2016 Jan 05, 2017 at 22:29:46 (UTC)
Goto Top
Hallo zusammen,

mit dem Beispiel von @131381 habe ich die "ListView" hinbekommen.
Vielen Dank.

Ich habe mein Script jetzt aber etwas umgebaut und würde gerne die Features nebeneinander wie auf dem Bild darstellen.
datagridview
Dies habe ich mit "DataGridView" soweit auch hinbekommen.
Nur leider bekomme ich die ScrollBar nicht einmal angezeigt und auch nicht zum funktionieren.

Eine ScrollBar bekomme ich nur angezeigt, wenn ich diese extra erstelle.
Wie ich diese aber dann zum funktionieren bekomme, keine Ahnung.

Habt Ihr noch einen Tipp?

Danke

Schöne Grüße

Markus2016

ScrollBar
$Global:FeatureScrollBar = New-Object System.Windows.Forms.VScrollBar
$Global:FeatureScrollBar.Location = New-Object System.Drawing.Point(580,0)
$Global:FeatureScrollBar.Size = New-Object System.Drawing.Size(20,420)
$Global:FeatureBox.Controls.Add($Global:FeatureScrollBar)

DataGridView
$Global:Feature = Get-WindowsOptionalFeature -Path "$Global:Projekt\Mount" | Where-Object {$_} | ForEach-Object {$_} | Select FeatureName, State  
$Global:FeatureName_I = @($Global:Feature | ForEach-Object {$_} | Sort-Object FeatureName | Select-Object -First 40)
$Global:FeatureName_II = @($Global:Feature | ForEach-Object {$_} | Sort-Object FeatureName | Select-Object -Skip 40 -First 40)
$Global:FeatureCheckbox = @()  

$Global:FeatureBox = New-Object System.Windows.Forms.DataGridView
$Global:FeatureBox.Location = New-Object System.Drawing.Point(350,70) 
$Global:FeatureBox.Size = New-Object System.Drawing.Size(600,420)
$Global:FeatureBox.DataBindings.DefaultDataSourceUpdateMode = 0
$Global:FeatureBox.ScrollBars = "vertical"  
$Global:FeatureBox.BackColor = "White"  
$Global:FeatureBox.BorderStyle = "none"  
$Global:Window.Controls.Add($Global:FeatureBox)

$i = 0
ForEach ($_ in $Global:FeatureName_I ) {

$Global:FeatureCheckbox_I = New-Object System.Windows.Forms.Checkbox
$Global:FeatureCheckbox_I.Text = $_.FeatureName
$Global:FeatureCheckbox_I.Name = $_.FeatureName
$Global:FeatureCheckbox_I.Tag = $_.State
$Global:FeatureCheckbox_I.DataBindings.DefaultDataSourceUpdateMode = 0
$Global:FeatureCheckbox += @($Global:FeatureCheckbox_I)
$Global:FeatureBox.Controls.Add($Global:FeatureCheckbox_I)
    
$i++
$Y = $i * 20

$Global:FeatureCheckbox_I.Location = New-Object System.Drawing.Size(0,($Y-20)) 
$Global:FeatureCheckbox_I.Size = New-Object System.Drawing.Size(290,20)

}

$i = 0
ForEach ($_ in $Global:FeatureName_II ) {

$Global:FeatureCheckbox_II = New-Object System.Windows.Forms.Checkbox
$Global:FeatureCheckbox_II.Text = $_.FeatureName
$Global:FeatureCheckbox_II.Name = $_.FeatureName
$Global:FeatureCheckbox_II.Tag = $_.State
$Global:FeatureCheckbox_II.DataBindings.DefaultDataSourceUpdateMode = 0
$Global:FeatureCheckbox += @($Global:FeatureCheckbox_II)
$Global:FeatureBox.Controls.Add($Global:FeatureCheckbox_II)
    
$i++
$Y = $i * 20

$Global:FeatureCheckbox_II.Location = New-Object System.Drawing.Size(290,($Y-20)) 
$Global:FeatureCheckbox_II.Size = New-Object System.Drawing.Size(290,20)
}

ListView
$Global:FeatureBox = New-Object System.Windows.Forms.ListView
$Global:FeatureBox.Location = New-Object System.Drawing.Point(350,70) 
$Global:FeatureBox.Size = New-Object System.Drawing.Size(590,420)
$Global:FeatureBox.Font = $Global:Schrift[2] 
$Global:FeatureBox.BorderStyle = "none"  
$Global:FeatureBox.CheckBoxes = $true
$Global:FeatureBox.Name = "FeatureBox"  
$Global:FeatureBox.DataBindings.DefaultDataSourceUpdateMode = 0
$Global:FeatureBox.MultiSelect = $false
$Global:FeatureBox.UseCompatibleStateImageBehavior = $false
$Global:FeatureBox.View = 1
$Global:FeatureBox.FullRowSelect = $true
$Global:Window.Controls.Add($Global:FeatureBox)

$ColumnName = New-Object System.Windows.Forms.ColumnHeader
$ColumnName.Width = 220
$ColumnName.Text = "Feature"  
$ColumnName.Name = "ColumnName"  
$Global:FeatureBox.Columns.Add($ColumnName)

$ColumnState = New-Object System.Windows.Forms.ColumnHeader
$ColumnState.Width = 60
$ColumnState.Text = "State"  
$ColumnState.Name = "ColumnState"  
$Global:FeatureBox.Columns.Add($ColumnState)

$Global:Feature | Select FeatureName, State | Where-Object{
        $Item = $Global:FeatureBox.Items.Add($_.FeatureName)
        $Item.SubItems.Add((@('Enabled') | Get-Random))  
    }
Mitglied: 131381
131381 Jan 06, 2017 updated at 08:03:16 (UTC)
Goto Top
Quark, eine Extra-Scrollbar brauchst du in keinem Fall, da die Controls diese Automatisch einblenden!! Ansonsten hast du die Property zum Anzeigen von Scrollleisten in den Controls falsch gesetzt. Du fügst immer noch Checkboxes per Control ein????????? Du hast das Prinzip leider nicht verstanden. Setzen 6 face-smile
Arbeite erst mal eine Woche mit VS und komm dann wieder...
Member: Markus2016
Markus2016 Jan 06, 2017 at 20:44:34 (UTC)
Goto Top
Hallo mikrotik,

ich glaube schon, dass ich das Prinzip einigermaßen verstanden habe. face-smile
Wenn ich dies anwende, finde ich aber leider keine Möglichkeit für folgendes:
- feste Spaltenbreite definieren
- Checkboxen anzeigen.
- Aufteilen der "FeatureName" zu gleichen Teilen auf die linke und rechte Reihe

Deswegen fand ich den Ansatz mit den Checkboxen per Control garnicht so schlecht, auch wenn dieser nicht dem Standard entspricht. face-wink

$Global:Feature = New-Object System.Data.DataTable
$NewColumns = New-Object System.Data.DataColumn Feature_1,([String]); $Global:Feature.Columns.Add($NewColumns)
$NewColumns = New-Object System.Data.DataColumn Feature_2,([String]); $Global:Feature.Columns.Add($NewColumns)

Get-WindowsOptionalFeature -Path "C:\Mount" | Where-Object {  
$Row = $Global:Feature.NewRow()
$Row.Feature_1 = ($_.FeatureName)
$Row.Feature_2 = ($_.FeatureName)
$Global:Feature.Rows.Add($Row)
}

$Global:FeatureDataGridView = New-Object System.Windows.Forms.DataGridView
$Global:FeatureDataGridView.Location = New-Object System.Drawing.Point(350,70) 
$Global:FeatureDataGridView.Size = New-Object System.Drawing.Size(600,420)
$Global:FeatureDataGridView.DataBindings.DefaultDataSourceUpdateMode = 0
$Global:FeatureDataGridView.ScrollBars = "vertical"  
$Global:FeatureDataGridView.BackgroundColor = "White"  
$Global:FeatureDataGridView.BorderStyle = "none"  
$Global:FeatureDataGridView.CellBorderStyle = "none"  
$Global:FeatureDataGridView.RowHeadersBorderStyle = "none"  
$Global:FeatureDataGridView.CheckBoxes = $true
$Global:FeatureDataGridView.MultiSelect = $true
$Global:FeatureDataGridView.DataSource = $Global:Feature
$Global:FeatureDataGridView.ColumnHeadersVisible = $false
$Global:FeatureDataGridView.RowHeadersVisible = $false

$Global:Window.Controls.Add($Global:FeatureDataGridView)

Habe VS zwar installiert, blicke aber gerade noch garnicht durch. face-sad

Wäre für ein paar Tipps trotzdem dankbar.

Schöne Grüße

Markus2016
Member: Markus2016
Markus2016 Jan 09, 2017 updated at 21:29:00 (UTC)
Goto Top
Hallo zusammen,

bin jetzt doch wieder bei der CheckedListBox angekommen. face-smile Dabei bleibt es jetzt auch.

Jetzt habe ich noch das Problem, das beim ersten Scrollen in den nachfolgenden Spalten die Schriftgröße größer als in den ersten Spalten dargestellt wird.
Durch anklicken der CheckBox oder durch Scrollen verändert sich das aber wieder?
Kann man die falsche Darstellung der Schriftgröße irgendwie verhindern?

Den Abstand zwischen den Zeilen bekommen ich leider auch nicht hin. Das sollte doch über ItemHeight gehen?

Bitte um Unterstützung.
Vielen lieben Dank.

Schöne Grüße
Markus2016

$Global:Feature = New-Object System.Data.DataTable
$NewColumns = New-Object System.Data.DataColumn Feature,([String]); $Global:Feature.Columns.Add($NewColumns)
$NewColumns = New-Object System.Data.DataColumn State,([String]); $Global:Feature.Columns.Add($NewColumns)

Get-WindowsOptionalFeature -Path "C:\Mount" | Where-Object {  
$Row = $Global:Feature.NewRow()
$Row.Feature = ($_.FeatureName)
$Row.State = ($_.State)
$Global:Feature.Rows.Add($Row)
}

$Global:FeatureBox = New-Object System.Windows.Forms.CheckedListBox
$Global:FeatureBox.Location = New-Object System.Drawing.Size(350,90) 
$Global:FeatureBox.Size = New-Object System.Drawing.Size(600,420)
$Global:FeatureBox.CheckOnClick = $true
$Global:FeatureBox.HorizontalScrollbar = $true
$Global:FeatureBox.ScrollAlwaysVisible = $false
$Global:FeatureBox.MultiColumn = $true
$Global:FeatureBox.Sorted = $true
$Global:FeatureBox.ColumnWidth = "300"  
$Global:FeatureBox.ThreeDCheckBoxes = $true
$Global:FeatureBox.DataSource = @($Global:Feature.Feature)
$Global:FeatureBox.DataBindings.DefaultDataSourceUpdateMode = 0
$Global:FeatureBox.BorderStyle = "none"  
$Global:Window.Controls.Add($Global:FeatureBox)
Member: Markus2016
Markus2016 Jan 28, 2017 at 14:14:39 (UTC)
Goto Top
Hallo zusammen,

jetzt funktioniert es wie ich möchte.

Danke für die Hilfe.

Schöne Grüße
Markus2016