我正在Powershell中寻找继承。我的Windows表单中有很多标签,groupBoxes,dropDowns等,例如:
$amuletLabelValueDmg = New-Object System.Windows.Forms.Label
$amuletLabelValueDmg.Location = New-Object System.Drawing.Size(10,20)
$amuletLabelValueDmg.Size = New-Object System.Drawing.Size(60,20)
$amuletLabelValueDmg.Text = 'Value'
$groupBoxAmulet.Controls.Add($amuletLabelValueDmg)
$amuletLabelHealth = New-Object System.Windows.Forms.Label
$amuletLabelHealth.Location = New-Object System.Drawing.Size(10,40)
$amuletLabelHealth.Size = New-Object System.Drawing.Size(60,20)
$amuletLabelHealth.Text = 'Health'
$groupBoxAmulet.Controls.Add($amuletLabelHealth)
$amuletLabelResistance = New-Object System.Windows.Forms.Label
$amuletLabelResistance.Location = New-Object System.Drawing.Size(10,60)
$amuletLabelResistance.Size = New-Object System.Drawing.Size(60,20)
$amuletLabelResistance.Text = 'Resistance'
$groupBoxAmulet.Controls.Add($amuletLabelResistance)
在这种情况下,我正在寻找Label的继承关系(或者您可以将自己的图片显示为groupBox或dropDown而不是label,princip相同)。我不想复制,粘贴Labels的hundreads,我想使用继承,而只是使用参数调用某些Class。
我尝试使用函数,但是很快我意识到我将永远只有一个实例,因此这将无法工作。我的朋友建议我在Powershell中使用Class之类的东西,而不是上面的那些行,只需用新实例调用该类。但是我有点迷茫。有人知道如何“复制”很多标签吗?我想象这样的解决方案:
class labelValueDmg {
variables and definition of label
}
$amuletLabelValueDmg = New-Object labelValueDmg
$beltLabelValueDmg = New-Object labelValueDmg
powershell中是否有类似的东西,或者您将如何解决此问题?如果您有50个标签,50个boxBoxes等...
[1]实际上,我找到了另一种解决方法。据我所知,您可以使用一个简单的函数来执行此操作。而且更有效。我这样声明函数>>
function createNewObject {
param (
[int[]] $Location,
[int[]] $Size,
[string] $Type,
[string] $Text
)
if ($Type -eq 'Label') { $newObject = New-Object System.Windows.Forms.Label }
elseif ($Type -eq 'TextBox') { $newObject = New-Object System.Windows.Forms.TextBox }
elseif ($Type -eq 'CheckBox') { $newObject = New-Object System.Windows.Forms.CheckBox }
elseif ($Type -eq 'Button') { $newObject = New-Object System.Windows.Forms.Button }
elseif ($Type -eq 'GroupBox') { $newObject = New-Object System.Windows.Forms.GroupBox }
elseif ($Type -eq 'RadioButton') { $newObject = New-Object System.Windows.Forms.RadioButton }
$newObject.Location = New-Object System.Drawing.Size $Location[0], $Location[1]
$newObject.Size = New-Object System.Drawing.Size $Size[0], $Size[1]
$newObject.Text = $Text
return $newObject
}
然后我将使用新变量调用此函数,例如>>
$amuletLabelValueDmg = createNewObject(20,10) (40,10) 'Label' 'Value'
$cloakTextBox = createNewObject(40,10) (40,10) 'TextBox' 'Cloak'
我认为这是仅用变量$ Type调用一个函数的好方法,其中我决定对象是标签,文本框还是其他对象。 毕竟,感谢您的代码,我以形式展示了对象。
$objForm.Controls.AddRange(@(
$amuletLabelValueDmg
$cloakTextBox
))
据我所知,这是解决我的问题的非常方便的方法。
答案 0 :(得分:1)
您可以使用以下技术显着减少代码中的“噪音”和重复性,该技术不需要继承/类型扩展 [1] :
将New-Object
与-Property
参数一起使用,您可以向其传递属性的 hashtable ,从而避免了先创建变量然后必须分别分配属性:
$amuletLabelValueDmg = New-Object Windows.Forms.Label -Property @{
Location = New-Object Drawing.Point 10, 20
Size = New-Object Drawing.Size 60, 20
Text = 'Value'
}
$groupBoxAmulet.Controls.Add($amuletLabelValueDmg)
注意:
我通过从类型名称中省略System.
前缀来进一步缩短了代码,在PowerShell中通常是 optional (Add-Type
,{ {1}}和Update-TypeData
调用以及Update-FormatData
和using assembly
语句)。
顺便说一句:请注意我如何更改某些using namespace
调用的语法,例如Drawing.Size(60,20)New-Object
New-Object Drawing.Size 60, 20 to
(60,20). The no-whitespace
60,20 syntax should be avoided, because it is based on mistaking the syntax for a _method call_, which it isn't:
-ArgumentList`参数;参数传递时不带括号,由空格分隔。
在 PSv5 + 中,您可以使用 casts 和静态is an array _argument_ that is bound to the (implied)
方法代替类型{{1 }},以及 ::new()
语句以缩短类型名称:
New-Object
无论哪种情况,您都可以创建简单的函数包装器(为简便起见,在此处使用PSv5 +;可以并且应该使该函数更健壮):
using namespace
最后,您可以通过将数组文字传递到容器控件的# Load the System.Windows.Forms assembly
# which implicitly loads System.Drawing too.
using assembly System.Windows.Forms
# Declare implied namespaces, so that types from
# the loaded assemblies can be referred to by mere name
# (e.g., 'Form' instead of 'System.Windows.Forms')
using namespace System.Windows.Forms
using namespace System.Drawing
$amuletLabelValueDmg = [Label] @{
Location = [Point]::new(10, 20)
Size = [Size]::new(60, 20)
Text = 'Value'
}
$groupBoxAmulet.Controls.Add($amuletLabelValueDmg)
方法(假设存在上面定义的function New-Label {
param(
[int[]] $Location,
[int[]] $Size,
[string] $Text
)
# Create and output a new label control
[Label] @{
Location = [Point]::new($Location[0], $Location[1])
Size = [Size]::new($Size[0], $Size[1])
Text = $Text
}
}
$amuletLabelValueDmg = New-Label 10,20 60,20 Value
函数)来减少对辅助变量的需求:
Controls.AddRange()
[1]虽然我个人认为这不值得,但如果您确实想通过继承/类型扩展来做到这一点,则必须附加自定义控件创建代码而不是单独的实例(请注意,New-Label
只会使控件类型对象 (例如 $groupBoxAmulet.Controls.AddRange(@(
New-Label 10,20 60,20 Value
New-Label 10,40 60,20 Health
New-Label 10,60 60,20 Resistance
))
)(例如[System.Windows.Forms.Label]
) 已经存在的实例上可用的新定义成员。
Update-TypeData -TypeName System.Windows.Forms.Label ...
答案 1 :(得分:-1)
您可以创建custom object
并添加methods
,这些设置将以您需要的方式设置通用属性。像这样:
$Label = New-Object System.Windows.Forms.Label
Add-Member -MemberType ScriptMethod `
-InputObject $Label `
-Name 'Value' `
-Value {
$This.Location = New-Object System.Drawing.Size(10,20)
$This.Size = New-Object System.Drawing.Size(60,20)
$This.Text = 'Value'
return $This
} -Force
Add-Member -MemberType ScriptMethod `
-InputObject $Label `
-Name 'Health' `
-Value {
$This.Location = New-Object System.Drawing.Size(10,40)
$This.Size = New-Object System.Drawing.Size(60,20)
$This.Text = 'Health'
return $This
} -Force
Add-Member -MemberType ScriptMethod `
-InputObject $Label `
-Name 'Resistance' `
-Value {
$This.Location = New-Object System.Drawing.Size(10,60)
$This.Size = New-Object System.Drawing.Size(60,20)
$This.Text = 'Resistance'
return $This
} -Force
$Value = $Label.Value()
$Health = $Label.Health()
$Resistance = $Label.Resistance()