Наследование атрибутов формы (Label, GroupBox и т. Д.) В powershell - PullRequest
0 голосов
/ 13 октября 2018

Я ищу наследство в powershell.У меня есть много меток, групповых ящиков, dropDowns и т. Д. В моей форме Windows, например, они выглядят так:

$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)

Я ищу наследование метки в этом случае (или вы можете представить себяgroupBox или dropDown вместо метки, принцип такой же).Я не хочу копировать, вставлять сотни меток, я хотел бы использовать наследование и просто вызывать некоторый класс с параметрами.

Я пытался использовать функцию, но очень скоро я понял, что у меня всегда будет только один экземпляр, так что это не будет работать.Мой друг посоветовал мне использовать что-то вроде Class в powershell, и вместо этих строк просто вызвать этот класс с новым экземпляром.Но я немного потерян.Кто-нибудь знает, как «копировать» множество этикеток?Я представляю решение, подобное этому:

class labelValueDmg {
    variables and definition of label 
}

$amuletLabelValueDmg = New-Object labelValueDmg
$beltLabelValueDmg = New-Object labelValueDmg

Есть ли что-то подобное в powershell или как бы вы решили эту проблему?Если у вас 50 ярлыков, 50 групповых ящиков и т. Д. *

[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, где я решаю, является ли объект меткой, textBox или чем-то еще.В конце концов, я показываю объект в форме благодаря вашему коду.

$objForm.Controls.AddRange(@(
    $amuletLabelValueDmg
    $cloakTextBox
))

Насколько я знаю, это очень удобный способ решения моей проблемы.

Ответы [ 2 ]

0 голосов
/ 14 октября 2018

Вы можете значительно сократить "шум" и повторяемость в вашем коде с помощью следующих методов, которые не требуют наследования / расширения типа [1] :


Используйте New-Object с параметром -Property , которому вы можете передать хеш-таблицу свойств, что позволяет избежать необходимости сначала создавать переменную, а затемприсваивать свойства индивидуально:

$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 (за исключением вызовов Add-Type, Update-TypeData и Update-FormatData и операторов using assembly и using namespace).

  • В стороне: Обратите внимание, как я изменил синтаксис некоторых вызовов New-Object, например Drawing.Size (60,20) to New-Object Drawing.Size 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: 60, 20 is an array _argument_ that is bound to the (implied) -ArgumentList` параметр;аргументы передаются без скобок, разделенных пробелами.


В PSv5 + вы можете сократить это с помощью cast и static ::new() method для литералов типов вместо New-Object, а также с оператором 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)

В любом случае вы можете создать простых функций-оболочек (здесь для краткости используется PSv5 +; функцию можно и нужно сделать гораздо более надежной):

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() элемента управления контейнера (предполагается наличие функции 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
  ))

[1] Пока ялично я думаю, что это того не стоит, если вы действительно хотите сделать это с расширениями наследования / типов , вам придется прикрепить свой собственный код создания элемента управления к объекту типа элемента (например, [System.Windows.Forms.Label]) вместо индивидуального экземпляров (обратите внимание, что, аналогично, Update-TypeData -TypeName System.Windows.Forms.Label ... сделает только новые определенные элементы доступными только для уже существующих экземпляров ).

# Define a Create() method for the label *type* that acts as a factory
# method and outputs a new label *instance*.
# Note that the method becomes an *instance method* of the *type* object.
Add-Member -Force -InputObject ([System.Windows.Forms.Label]) -MemberType ScriptMethod `
           -Name Create -Value {                                                                #`#
  param(
    [int[]] $Location,
    [int[]] $Size,
    [string] $Text
  )
  New-Object $this.FullName -Property @{
    Location = New-Object Drawing.Point $Location[0], $Location[1]
    Size = New-Object Drawing.Size $Size[0], $Size[1]
    Text = $Text
  } 
}

# Call the type's new instance method with the desired arguments.
$amuletLabelValueDmg = [System.Windows.Forms.Label].Create((10,20), (60,20), 'Value')
0 голосов
/ 14 октября 2018

Вы можете создать 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...