使用powershell windows窗体创建一个带有多行标题的列表视图

问题描述 投票:0回答:1

我需要一个可以支持包含两行文本的列标题的列表视图。 我花了很多时间尝试使用 add_DrawColumnHeader 来创建第二行。 我在 C# 中创建它没有任何问题,但 powershell 似乎难以捉摸。

使用矩形加载 e.Graphics.Drawstring 时,出现此错误:

Cannot convert argument "point", with value: "{X=60,Y=8,Width=60,Height=8}", for "DrawString" to type "System.Drawing.PointF"

当我检查过载是否可用时,我看到了这一点,所以它应该可以工作:

OverloadDefinitions
-------------------
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, float x, float y)
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.RectangleF layoutRectangle)
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.RectangleF layoutRectangle, System.Drawing.StringFormat format)
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.PointF point)
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, float x, float y, System.Drawing.StringFormat format)
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.PointF point, System.Drawing.StringFormat format)

如果我使用 Visual Studio Powershell 表单,我不会收到错误,但也不会收到列.. LOL

这是我的代码的简化示例:

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$form = New-Object System.Windows.Forms.Form
$form.Text = "ListView with Custom Column Headers"
$form.Size = New-Object System.Drawing.Size(400, 300)

$listView1 = New-Object System.Windows.Forms.ListView
$listView1.Location = New-Object System.Drawing.Point(10, 10)
$listView1.Size = New-Object System.Drawing.Size(380, 200)
$listView1.View = [System.Windows.Forms.View]::Details
$listView1.OwnerDraw = $true

# Add columns
$columnHeader1 = New-Object System.Windows.Forms.ColumnHeader
$columnHeader1.Tag = "First Line`nSecond Line"

$columnHeader2 = New-Object System.Windows.Forms.ColumnHeader
$columnHeader2.Tag = "Third Line`nFourth Line"

$listView1.Columns.AddRange(@($columnHeader1, $columnHeader2))

# Add items for demonstration
$listView1.Items.Add("Item 1") | Out-Null
$listView1.Items[0].SubItems.Add("Subitem 1") | Out-Null

$listView1.Items.Add("Item 2") | Out-Null
$listView1.Items[1].SubItems.Add("Subitem 2") | Out-Null

$listView1.Items.Add("Item 3") | Out-Null
$listView1.Items[2].SubItems.Add("Subitem 3") | Out-Null

# Subscribe to the DrawColumnHeader event
$listView1.add_DrawColumnHeader({
    param($sender, $e)
    $e.DrawDefault = $false
    $Global:ee = $e

    # Draw two rows of text
    $sf = New-Object System.Drawing.StringFormat
    $sf.LineAlignment = [System.Drawing.StringAlignment]::Center
    $sf.Alignment = [System.Drawing.StringAlignment]::Center
    $HalfHeight = $e.Bounds.Height / 2
    $TopHeightHalf = $e.Bounds.Top + $e.Bounds.Height / 2
$firstLineRect = New-Object System.Drawing.Rectangle ($e.Bounds.Left, $e.Bounds.Top, $e.Bounds.Width, $e.Bounds.Height / 2)
$secondLineRect = New-Object System.Drawing.Rectangle ($e.Bounds.Left,$e.Bounds.Top + $e.Bounds.Height / 2 , $e.Bounds.Width, $HalfHeight)

    $e.Graphics.DrawString("First Line", $listView1.Font, [System.Drawing.Brushes]::Black, $firstLineRect, $sf)
    $e.Graphics.DrawString("Second Line", $listView1.Font, [System.Drawing.Brushes]::Black, $secondLineRect, $sf)
})

# Add ListView control to the form
$form.Controls.Add($listView1)

# Show the form
$form.ShowDialog() | Out-Null
powershell listview rectangles drawstring
1个回答
0
投票

简短回答

改变:

$firstLineRect = New-Object System.Drawing.Rectangle ($e.Bounds.Left, $e.Bounds.Top, $e.Bounds.Width, $e.Bounds.Height / 2)

$firstLineRect = New-Object System.Drawing.RectangleF ($e.Bounds.Left, $e.Bounds.Top, $e.Bounds.Width, $e.Bounds.Height / 2)
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>    ^ RectangleF

长答案

这似乎是由 PowerShell 与 C# 进行类型强制转换的方式不同引起的 - 您的代码使用以下类型将参数传递给

DrawString

$e.Graphics.DrawString(
    "First Line",                    # System.String
    $listView1.Font,                 # System.Drawing.Font
    [System.Drawing.Brushes]::Black, # System.Drawing.SolidBrush
    $firstLineRect,                  # System.Drawing.Rectangle
    $sf                              # System.Drawing.StringFormat
)

这些参数没有完全匹配 -

DrawString
的重载是:

write-host ($e.Graphics.DrawString | out-string)

OverloadDefinitions
-------------------
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, float x, float y)
void DrawString(System.ReadOnlySpan[char] s, System.Drawing.Font font, System.Drawing.Brush brush, float x, float y)
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.PointF point)
void DrawString(System.ReadOnlySpan[char] s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.PointF point)
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, float x, float y, System.Drawing.StringFormat format)
void DrawString(System.ReadOnlySpan[char] s, System.Drawing.Font font, System.Drawing.Brush brush, float x, float y, System.Drawing.StringFormat format)
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.PointF point, System.Drawing.StringFormat format)
void DrawString(System.ReadOnlySpan[char] s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.PointF point, System.Drawing.StringFormat format)
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.RectangleF layoutRectangle)
void DrawString(System.ReadOnlySpan[char] s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.RectangleF layoutRectangle)
void DrawString(string s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.RectangleF layoutRectangle, System.Drawing.StringFormat format)
void DrawString(System.ReadOnlySpan[char] s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.RectangleF layoutRectangle, System.Drawing.StringFormat format)

C# 编译器实现

System.Drawing.SolidBrush
继承自
System.Drawing.Solid
,并且还找到
RectangleF.Implicit(Rectangle to RectangleF)
的隐式转换运算符,并使用它来调用以下重载:

void DrawString(
    string s,
    System.Drawing.Font font,
    System.Drawing.Brush brush,
    System.Drawing.RectangleF layoutRectangle,
    System.Drawing.StringFormat format
)

另一方面,PowerShell 似乎正在尝试绑定到此重载:

void DrawString(
    string s,
    System.Drawing.Font font,
    System.Drawing.Brush brush,
    System.Drawing.PointF point,
    System.Drawing.StringFormat format
)

并且错误表明它无法将

$firstLineRect
System.Drawing.Rectangle
)转换为
System.Drawing.PointF
参数的
point

如果您显式地将

System.Drawing.RectangleF
分配给
$firstLineRect
,PowerShell 将选择与 C# 相同的重载,那么您就成功了...

(但不要忘记将

System.Drawing.RectangleF
也分配给
$secondLineRect

© www.soinside.com 2019 - 2024. All rights reserved.