Here's the code I have so far below which is populated with an array ([System.Drawing.Color] | Get-Member -Static -MemberType Properties).name
.
I was trying to see if there was any way to set the BackColor
property of each item to match that of the same array element of colours but there's none.
Ideally, I'd like to get something like this with a little swatch of the colours to the left of the name.
EDIT: I've since found that you can add an event handler for the control but I'm still unsure how to change each item to show a little swatch. I've updated the code below as the other coded wasn't that close.
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.Font = [System.Drawing.Font]::New("Segoe UI", 10, [System.Drawing.FontStyle]::Regular) # Bold, Italic, Regular, Strikeout or Underline
$Form.StartPosition = 'CenterScreen'
$Form.Text = 'How do I Change Each Items Colour to Match Their Name?'
$Form.Width = 500
$Form.Height = 69
$Form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle # 1 A fixed, single-line border
$Form.SizeGripStyle = [System.Windows.Forms.SizeGripStyle]::Hide # 2 The sizing grip is hidden.
$combo = New-Object System.Windows.Forms.ComboBox
$combo.DrawMode = 'OwnerDrawFixed'
$combo.FlatStyle = [System.Windows.Forms.FlatStyle]::System
$combo.Font = [System.Drawing.Font]::New("Segoe UI", 14, [System.Drawing.FontStyle]::Regular) # Bold, Italic, Regular, Strikeout or Underline
$combo.Width = $Form.Width-1-$combo.Height+($combo.Margin.Left+$combo.Margin.Right)
$combo.AutoCompleteMode = 'SuggestAppend' # Enables searching but not mid string. Need to find a solution for this.
$combo.AutoCompleteSource = 'ListItems'
$combo.AutoSize = $true
$combo.DropDownStyle = 'DropDownList'
$combo.ItemHeight = 24
$colorNamesArr = ([System.Drawing.Color] | Get-Member -Static -MemberType Properties).name # Here's the array of colour that are to get added to the ComboBox.
$combo.Items.AddRange($colorNamesArr) # Add the array to the ComboBox.
$Form.Controls.Add($combo)
# HERE'S WHERE I NEED HELP.
# How do I change the colours of the ComboBox items to match that of their name.
$combo.Add_DrawItem({param($sender,$e)
$text = "-- Select Color --"
if ($e.Index -gt -1){
$text = $sender.GetItemText($sender.Items[$e.Index])
}
$e.DrawBackground()
[System.Windows.Forms.TextRenderer]::DrawText($e.Graphics, $text, $combo.Font, $e.Bounds, $e.ForeColor, [System.Windows.Forms.TextFormatFlags]::Default)
})
$Form.ShowDialog() | Out-Null
$Form.Dispose()
You need to override the event that draws the ComboBox. Here is a sample of how you might do it, if you wanted to add a colour next to each name.
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.StartPosition = 'CenterScreen'
$Form.Text = "How do I Change Each Items Colour to Match Their Name?"
$Form.Width = 500
$Form.Height = 72
$cbSearch = New-Object system.Windows.Forms.ComboBox
$cbSearch.Font = [System.Drawing.Font]::New("Segoe UI", 14, [System.Drawing.FontStyle]::Regular) # Bold, Italic, Regular, Strikeout or Underline
$cbSearch.Width = $Form.Width-1-$cbSearch.Height+($cbSearch.Margin.Left+$cbSearch.Margin.Right)
$cbSearch.DropDownStyle = 'DropDownList'
# Setting up the ComboBox.
$colorNamesArr = ([System.Drawing.Color] | Get-Member -Static -MemberType Properties).name
#Add the array to the ComboBox.
$colorNamesArr | ForEach-Object {[void] $cbSearch.Items.Add($_)}
#Set the first item when opened.
$cbSearch.Text = $colorNamesArr[0]
## Allow override of graphical rendering of the Combobox.
$cbSearch.DrawMode = [System.Windows.Forms.DrawMode]::OwnerDrawFixed
## Add an event that draws each item.
$cbSearch.add_DrawItem({
param([object]$s, [System.Windows.Forms.DrawItemEventArgs]$e)
$Graphics = $e.Graphics
$Rectangle = $e.Bounds
# Clear the previous drawing
$e.DrawBackground()
if ($e.Index -ge 0) {
$Name = ([System.Windows.Forms.ComboBox]$s).Items[$e.Index].ToString()
$Font = [System.Drawing.Font]::new("Arial", 10, [System.Drawing.FontStyle]::Regular)
$Color = [System.Drawing.Color]::FromName($Name)
$Brush = [System.Drawing.SolidBrush]::new($Color)
# Can uncomment this if you do not want the background highlighted when hovering over item.
# $Graphics.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::AntiAliasGridFit
$Graphics.DrawString($Name, $Font, [System.Drawing.Brushes]::Black, $Rectangle.X, $Rectangle.Top)
$Graphics.FillRectangle($Brush, $Rectangle.X + 110, $Rectangle.Y + 5, $Rectangle.Width -10, $Rectangle.Height -10)
# Dispose of disposable objects
$Brush.Dispose()
}
})
# Add any controls to the form.
$Form.Controls.Add($cbSearch)
# This below needs to be added to focus the dialog when it opens after the ColorDialog.
$Form.Add_Shown({$Form.Activate(); $cbSearch.Focus()})
[void]$Form.ShowDialog()
Play around with the settings to change the drawing to your preference.
Adapted to PowerShell from this code.
EDIT
If you want to change the position and size of the coloured boxes, see this example.
$Graphics.DrawString($Name, $Font, [System.Drawing.Brushes]::Black, $Rectangle.X + 40, $Rectangle.Top + 5)
$Graphics.FillRectangle($Brush, $Rectangle.X + 10, $Rectangle.Y + 2, $Rectangle.Width - 440, $Rectangle.Height - 4)
X and Y cover the positioning within the box of an object. Height and Width is the size of the box itself.