WinForm inside hashtable

196 views Asked by At

I can set form elements inside hashtable:

$Hash = @{}

$Hash.Main = New-Object System.Windows.Forms.Form
$Hash.Main.Left = 0
$Hash.Main.Top = 0
...
$Hash.Label = New-Object System.Windows.Forms.Label
$Hash.Label.Left = 0
$Hash.Label.Top = 0
...
$Hash.Panel = New-Object System.Windows.Forms.Panel
$Hash.Panel.Left = 0
$Hash.Panel.Top = 0
...

How can I write the same thing inside hashtable? I tried to make it as if it could be. And it works. But is this syntax correct?

$Hash = @{

   Main = [System.Windows.Forms.Form] @{

      Left = 0
      Top = 0
      ...
   }

   Label = [System.Windows.Forms.Label] @{

      Left = 0
      Top = 0
      ...
   }

   Panel = [System.Windows.Forms.Panel] @{

      Left = 0
      Top = 0
      ...
   }
}

Thank you

1

There are 1 answers

0
JosefZ On BEST ANSWER

Yes, this syntax is correct:

Creating Objects from Hash Tables

Beginning in PowerShell 3.0, you can create an object from a hash table of properties and property values.

The syntax is as follows:

[<class-name>]@{
  <property-name>=<property-value>
  <property-name>=<property-value>
  …
}

This method works only for classes that have a null constructor, that is, a constructor that has no parameters. The object properties must be public and settable.

For more information, see about_Object_Creation.

Check the first condition (a constructor that has no parameters):

[System.Drawing.Font],        ### does not have empty constructor 
[System.Windows.Forms.Form],
[System.Windows.Forms.Label],
[System.Windows.Forms.Panel] |
    Where-Object { 
        'new' -in ( $_ | 
            Get-Member -MemberType Methods -Static | 
                Select-Object -ExpandProperty Name ) -and
        $_::new.OverloadDefinitions -match ([regex]::Escape('new()'))
    } | Select-Object -ExpandProperty FullName
System.Windows.Forms.Form
System.Windows.Forms.Label
System.Windows.Forms.Panel

Check the latter condition (object properties must be public and settable):

[System.Windows.Forms.Form],
[System.Windows.Forms.Label],
[System.Windows.Forms.Panel] | 
    ForEach-Object {
        @{ $_.FullName = ( 
            $_.GetProperties('Instance,Public') | Where-Object CanWrite |
                Select-Object -ExpandProperty Name | Sort-Object
           )
        }
    }
Name                           Value
----                           -----
System.Windows.Forms.Form      {AcceptButton, AccessibleDefaultActionDescription, Acc...
System.Windows.Forms.Label     {AccessibleDefaultActionDescription, AccessibleDescrip...
System.Windows.Forms.Panel     {AccessibleDefaultActionDescription, AccessibleDescrip...

Getting both above code snippets together is a trivial task…