PowerShell and Winforms, Trying to change the selection color of a ComboBox set to DropDownList and OwnerDrawFixed

huangapple go评论67阅读模式
英文:

PowerShell and Winforms, Trying to change the selection color of a ComboBox set to DropDownList and OwnerDrawFixed

问题

我看了这个:https://stackoverflow.com/questions/11649803/change-the-selection-color-of-a-winforms-combobox

还有这个网站上的许多其他帖子,但都没有适用于我。我认为可能是我将C#代码调整到我的应用程序的方式。

这是表单的屏幕截图:

PowerShell and Winforms, Trying to change the selection color of a ComboBox set to DropDownList and OwnerDrawFixed

我试图更改下拉框的样式。当你将ComboBox切换为DropDownList时,ComboBox的样式会更改为较深的灰色(查看除"Separation Model"之外的所有下拉框)。

我已将其中一个下拉框更改为OwnerDrawFixed,然后使用DrawItem事件处理程序处理文本和背景的绘制。

以下是代码:

$COMBO_SeparationModel_DrawItem = {

    param(
        [System.Object]
        $sender, 
        [System.Windows.Forms.DrawItemEventArgs]
        $e
    )

    $Brush = [System.Drawing.SolidBrush]::new([System.Drawing.Color]::Black)  
    $Point = [System.Drawing.Point]::new(2, $e.Index * $e.Bounds.Height + 1) 
    $index = $e.Index -ge 0 ? $e.Index : 0  
    
    $ptx = $e.Bounds.X
    $pty = $e.Bounds.Y
    $pt = [System.Drawing.PointF]::new($ptx,$pty)

    $e.DrawBackground()

    if (($e.State -and [System.Windows.Forms.DrawItemState]::Selected) -eq [System.Windows.Forms.DrawItemState]::Selected){
        $e.Graphics.FillRectangle([System.Drawing.SolidBrush]::new([System.Drawing.Color]::Azure), $e.Bounds)
    }else{
        # $e.Graphics.FillRectangle([System.Drawing.SolidBrush]::new($COMBO_SeperationModel.BackColor), $e.Bounds)  
        $e.Graphics.FillRectangle([System.Drawing.SolidBrush]::new($COMBO_SeperationModel.BackColor), [System.Drawing.Rectangle]::new($Point, $e.Bounds.Size))  
    }      
    
    $e.Graphics.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::AntiAliasGridFit
    $e.Graphics.DrawString($COMBO_SeperationModel.Items[$index].ToString(), $e.Font, $Brush, $pt, [System.Drawing.StringFormat]::GenericDefault); 
    $e.DrawFocusRectangle()

}

$DemucsForm_Load = {
    # $wshell = New-Object -ComObject Wscript.Shell
    # $wshell.Popup($e.State,0,"Done",0x1)
}

. (Join-Path $PSScriptRoot 'DemucsForm.designer.ps1')

Add-Type -AssemblyName PresentationCore,PresentationFramework
[System.Windows.Forms.Application]::EnableVisualStyles()

$FORM_VSYSDemucsUI.ShowDialog()

但是当我运行这个代码时,所有都是Azure,而不仅仅是所选的项目:

PowerShell and Winforms, Trying to change the selection color of a ComboBox set to DropDownList and OwnerDrawFixed

另一个问题/副作用是,进入自定义的DrawItem事件处理程序后,论坛上的Label组件不再具有抗锯齿效果。请查看标题下的"10 Total Files Selected..."文本。

我感觉已经尝试了一切,但就是无法让它起作用。

有人可以看一看并告诉我我在做错什么吗?

我会非常感激任何帮助,这样我就可以继续构建功能。

英文:

I've looked at this: https://stackoverflow.com/questions/11649803/change-the-selection-color-of-a-winforms-combobox

And many other posts on this site, but none have worked out for me. I think it might be the way I'm adapting the C# code to my app.

Here's a screenshot of the form:

PowerShell and Winforms, Trying to change the selection color of a ComboBox set to DropDownList and OwnerDrawFixed

I'm trying to change the style of the dropdowns. When you switch a ComboBox to DropDownList, the style of the ComboBox changes to a darker gray color (See all of the dropdowns other than "Separation Model).

I've changed one of the dropdowns to OwnerDrawFixed, and then I'm handling the drawing of the text and background with a DrawItem event handler.

Here's the code:

$COMBO_SeparationModel_DrawItem = {

	param(
        [System.Object]
        $sender, 
        [System.Windows.Forms.DrawItemEventArgs]
        $e
    )

    $Brush = [System.Drawing.SolidBrush]::new([System.Drawing.Color]::Black)  
    $Point = [System.Drawing.Point]::new(2, $e.Index * $e.Bounds.Height + 1) 
    $index = $e.Index -ge 0 ? $e.Index : 0  
    
    $ptx = $e.Bounds.X
    $pty = $e.Bounds.Y
    $pt = [System.Drawing.PointF]::new($ptx,$pty)

    $e.DrawBackground()

    if (($e.State -and [System.Windows.Forms.DrawItemState]::Selected) -eq [System.Windows.Forms.DrawItemState]::Selected){
        $e.Graphics.FillRectangle([System.Drawing.SolidBrush]::new([System.Drawing.Color]::Azure), $e.Bounds)
    }else{
        # $e.Graphics.FillRectangle([System.Drawing.SolidBrush]::new($COMBO_SeperationModel.BackColor), $e.Bounds)  
        $e.Graphics.FillRectangle([System.Drawing.SolidBrush]::new($COMBO_SeperationModel.BackColor), [System.Drawing.Rectangle]::new($Point, $e.Bounds.Size))  
    }      
    
    $e.Graphics.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::AntiAliasGridFit
    $e.Graphics.DrawString($COMBO_SeperationModel.Items[$index].ToString(), $e.Font, $Brush, $pt, [System.Drawing.StringFormat]::GenericDefault); 
    $e.DrawFocusRectangle()

}

$DemucsForm_Load = {
     # $wshell = New-Object -ComObject Wscript.Shell
     # $wshell.Popup($e.State,0,"Done",0x1)
}

. (Join-Path $PSScriptRoot 'DemucsForm.designer.ps1')

Add-Type -AssemblyName PresentationCore,PresentationFramework
[System.Windows.Forms.Application]::EnableVisualStyles()

$FORM_VSYSDemucsUI.ShowDialog()

But when I run this code, everything is Azure instead of only the selected item:

PowerShell and Winforms, Trying to change the selection color of a ComboBox set to DropDownList and OwnerDrawFixed

Another problem / side-effect is that after I entered my custom DrawItem event handler, the Label components on the forum are no longer anti-aliased. See the "10 Total Files Selected..." text under the header.

I feel like I've tried everything and I just can't get it to work.

Can someone take a look and tell me what I'm doing wrong?

I would really appreciate any help so I can move on to actually building out the functionality.

答案1

得分: 1

以下是已经翻译好的部分:

  • 如何自定义 ComboBox 的绘制方式。
  • 如何处理释放 GDI+ 对象(如 Brush)。
  • 如何使窗体 DPI 感知。

PowerShell and Winforms, Trying to change the selection color of a ComboBox set to DropDownList and OwnerDrawFixed

using assembly System.Windows.Forms
using namespace System.Windows.Forms
using namespace System.Drawing
using namespace System
# 启用视觉样式
[Application]::EnableVisualStyles()

# 启用 DPI 感知
$code = @"
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool SetProcessDPIAware();
"@
$Win32Helpers = Add-Type -MemberDefinition $code -Name "Win32Helpers" -PassThru
$null = $Win32Helpers::SetProcessDPIAware()

$form = [Form] @{
    ClientSize = [Point]::new(500, 200);
    StartPosition = "CenterScreen";
    Text = "Test";
    AutoScaleDimensions = [SizeF]::new(6, 13);
    AutoScaleMode = [AutoScaleMode]::Font;
}
$comboBox1 = [ComboBox] @{
    Location = [Point]::new(8,8);
    Width = 300;
    DataSource = ("Lorem", "Ipsum", "Dolor", "Sit", "Amet");
    DropDownStyle = [ComboBoxStyle]::DropDownList;
    DrawMode = [DrawMode]::OwnerDrawFixed;
}
$comboBox1.Add_DrawItem({param([Object]$sender, [DrawItemEventArgs]$e)
    $txt = ""
    if($e.Index -ge 0)
    {
        $txt = $comboBox1.GetItemText($comboBox1.Items[$e.Index])
    }
    $bgColor = [Color]::White
    if(($e.State -band [DrawItemState]::Selected) -eq [DrawItemState]::Selected) 
    {
        $bgColor = [Color]::Tomato
    }
    $fColor = [Color]::Black
    if(($e.State -band [DrawItemState]::Selected) -eq [DrawItemState]::Selected)
    {
        $fColor = [Color]::White
    }
    $bgBrush = [SolidBrush]::new($bgColor)
    try
    { 
        $e.Graphics.FillRectangle($bgBrush, $e.Bounds)
        [TextRenderer]::DrawText($e.Graphics,$txt, $e.Font,
            $e.Bounds, $fColor, $bgColor, 
            ([TextFormatFlags]::Left -bor [TextFormatFlags]::VerticalCenter))
    }
    finally
    {
        $bgBrush.Dispose()
    }
});
$form.Controls.Add($comboBox1)
$null = $form.ShowDialog()
英文:

The following example shows:

  • How you can customize drawing of a ComboBox.
  • How you must take care of disposing GDI+ objects like Brush
  • How you can make the form DPI aware

PowerShell and Winforms, Trying to change the selection color of a ComboBox set to DropDownList and OwnerDrawFixed

using assembly System.Windows.Forms
using namespace System.Windows.Forms
using namespace System.Drawing
using namespace System
#Enable visual styles
[Application]::EnableVisualStyles()

#Enable DPI awareness
$code = @"
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool SetProcessDPIAware();
"@
$Win32Helpers = Add-Type -MemberDefinition $code -Name "Win32Helpers" -PassThru
$null = $Win32Helpers::SetProcessDPIAware()

$form = [Form] @{
    ClientSize = [Point]::new(500, 200);
    StartPosition = "CenterScreen";
    Text = "Test";
    AutoScaleDimensions = [SizeF]::new(6, 13);
    AutoScaleMode = [AutoScaleMode]::Font;
}
$comboBox1 = [ComboBox] @{
    Location = [Point]::new(8,8);
    Width = 300;
    DataSource = ("Lorem", "Ipsum", "Dolor", "Sit", "Amet");
    DropDownStyle = [ComboBoxStyle]::DropDownList;
    DrawMode = [DrawMode]::OwnerDrawFixed;
}
$comboBox1.Add_DrawItem({param([Object]$sender, [DrawItemEventArgs]$e)
    $txt = ""
    if($e.Index -ge 0)
    {
        $txt = $comboBox1.GetItemText($comboBox1.Items[$e.Index])
    }
    $bgColor = [Color]::White
    if(($e.State -band [DrawItemState]::Selected) -eq [DrawItemState]::Selected) 
    {
        $bgColor = [Color]::Tomato
    }
    $fColor = [Color]::Black
    if(($e.State -band [DrawItemState]::Selected) -eq [DrawItemState]::Selected)
    {
        $fColor = [Color]::White
    }
    $bgBrush = [SolidBrush]::new($bgColor)
    try
    { 
        $e.Graphics.FillRectangle($bgBrush, $e.Bounds)
        [TextRenderer]::DrawText($e.Graphics,$txt, $e.Font,
            $e.Bounds, $fColor, $bgColor, 
            ([TextFormatFlags]::Left -bor [TextFormatFlags]::VerticalCenter))
    }
    finally
    {
        $bgBrush.Dispose()
    }
});
$form.Controls.Add($comboBox1)
$null = $form.ShowDialog()

huangapple
  • 本文由 发表于 2023年2月18日 14:07:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75491531.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定