2013年1月27日日曜日

DataBinding(その1)

データ・バインディングとは?

    「Binding」クラス・インスタンス値を、マークアップ拡張機能を使って
  指定した依存関係プロパティへデータ値としてセットする機能

                                                         (Xamlな)マークアップ拡張機能
                                                      ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
<TextBox Margin="10" Text="{Binding ElementName=sldrSlider, Path=Value}"/>
                                        ④        ①                           ②                             ③

                ①Bindingクラス名(System.Windows.Data.Binding)

                ②初期化パラメータ1
                     :ElementNameプロパティに(名前付けされた)ソースエレメント名を指定

                ③初期化パラメータ2
                    :Pathプロパティに(名前付けされた)ソースエレメントのプロパティを指定

                ④TextBoxエレメントのText依存関係プロパティに指定する

 

例 ← 「Slider」の値をTextBoxに数値として表示

(コード)

#------------------------------------------------------
if ($host.Version.Major -eq 3) {
    powershell.exe
} else {
    powershell.exe -version 2 -sta
}

$xaml = @'
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Markup Extensions" Height="120" Width="175">

    <StackPanel>
        <TextBox Margin="10" Text="{Binding ElementName=sldrSlider, Path=Value}"/>
        <Slider Name="sldrSlider" TickPlacement="TopLeft" Margin="10"/>
    </StackPanel>

</Window>
'@

if ($host.Version.Major -eq 3) {
    add-type -assembly WindowsBase,PresentationCore,PresentationFramework,System.Xml,System.Xaml
} else {
    add-type -assembly WindowsBase,PresentationCore,PresentationFramework,System.Xml
}

$form = [System.Windows.Markup.XamlReader]::Parse($xaml)
$Form.ShowDialog() | out-null

#設定値を表示してみる。
$form.content.children[0].text      #<--TextBlockエレメントの文字列


(画面)
image

       

 







    受け取り側TextBoxのすべての依存関係プロパティ(除:Inheritなもの)
    (> $form.Content.Children[0] | dp2: )

    Name DP Type Value base
  =============== ========== ========================== ====
  IsMouseDirectlyOver Indirect,Xaml False Local
  IsKeyboardFocused Indirect,Xaml False Local
Text WPF Binding 4.67741935483871 Local
  IsMouseCaptured Indirect,Xaml False Local
  PageHeight Indirect,Xaml 18 Local
  Instance Indirect,Xaml System.Windows.Documents.TextEditor Local
  UndoManagerInstance Indirect,Xaml MS.Internal.Documents.UndoManager Local
  Margin WPF Direct 10,10,10,10 Local
  IsSelectionActive Indirect,Xaml False Local


    送り出し側のSliderのすべての依存関係プロパティ(除:Inheritなもの)
   (> $form.findname("sldrSlider") | dp2: )

    Name DP Type Value base
  =============== ========== ========================== ====
  Margin WPF Direct 10,10,10,10 Local
  IsKeyboardFocused Indirect,Xaml False Local
   Name WPF Direct sldrSlider Local
Value WPF Direct 4.67741935483871 Local
  PageHeight Indirect,Xaml 18 Local
  Instance Indirect,Xaml System.Windows.Documents.TextEditor Local
  UndoManagerInstance Indirect,Xaml MS.Internal.Documents.UndoManager Local
  TickPlacement WPF Direct TopLeft Local


Bidingインスタンスを見てみる
 
     改めて、上記例で以下の流れでBindingをたどってみる    <--逆からは辿れない
    > ターゲット・コントロール -> 依存関係プロパティ -> BindingExpression –> Binding
                       ①                           ②                              ③                       ④
    ①ターゲットコントロール
        > $form.Content.Children[0]
    ②依存関係プロパティ
    > $dp = [System.Windows.Markup.Primitives.MarkupWriter]::GetMarkupObjectFor(`
                 $form.Content.Children[0]).properties |
Select-Object -First 1

  Property Value
  ================= ==================================
  Name Text
  PropertyType System.String
  PropertyDescriptor MS.Internal.ComponentModel.DependencyObjectPropertyDescriptor
  IsAttached False
★  DependencyProperty Text
  Value 4.67741935483871
  Attributes {System.CLSCompliantAttribute,Chars,MS.Internal.ComponentModel.DependencyPropertyAttribute,System.SerializableAttribute...}
  IsComposite False
  StringValue 4.67741935483871
  Items {System.Windows.Markup.Primitives.ElementMarkupObject}
  TypeReferences {}
  IsConstructorArgument False
  IsValueAsString False
  IsContent False
  IsKey False


    ③BindingExpressionインスタンス
     > ($form.Content.Children[0]).GetBindingExpression($dp)

  Property名 Value
  ============== =================================================
  ParentBinding System.Windows.Data.Binding
  DataItem System.Windows.Controls.Slider Minimum:0 Maximum:10 Value:4.67741935483871
  ResolvedSource System.Windows.Controls.Slider Minimum:0 Maximum:10 Value:4.67741935483871
  ResolvedSourcePropertyName Value
Target System.Windows.Controls.TextBox: 4.677
TargetProperty Text
  ParentBindingBase System.Windows.Data.Binding
  BindingGroup  
  Status Active
  ValidationError  
  HasError False
  HasValidationError False
  IsDirty False
  ValidationErrors  


   ④ちなみに、Bindingインスタンスも見てみる
   > ($form.Content.Children[0]).GetBindingExpression($dp).ParentBinding

  Property名 Value
  ================ =================
  ValidationRules {}
  ValidatesOnExceptions False
  ValidatesOnDataErrors False
  ValidatesOnNotifyDataErrors True
  Path System.Windows.PropertyPath
  XPath  
  Mode Default
  UpdateSourceTrigger Default
  NotifyOnSourceUpdated False
  NotifyOnTargetUpdated False
  NotifyOnValidationError False
  Converter  
  ConverterParameter  
  ConverterCulture  
  Source  
  RelativeSource  
ElementName sldrSlider
  IsAsync False
  AsyncState  
  BindsDirectlyToSource False
  UpdateSourceExceptionFilter  
  FallbackValue {DependencyProperty.UnsetValue}
  StringFormat  
  TargetNullValue {DependencyProperty.UnsetValue}
  BindingGroupName  
  Delay 0


   次は、DataBindingの「方向」と「トリガー」について

依存関係プロパティ(その2)


依存関係プロパティ(DependecyProperty)について(その2)


    依存関係プロパティ定義で「inherit」を指定しておくと、
     WPF「ロジカルな階層構造」の下へ、指定した値がが継承されて行く

    「inherit」の定義例
    > System.Windows.Controls.Button]::FontWeightProperty.DefaultMetadata.Inherits
      True   <--★これ

    サンプル画面 <--「Button2」にはFontWeightは指定がないが、
                                「StackPanel」でBoldにしてされている

imageコードはこのBlogの一番下

   「inherit」の追っかけ方(その1:下からさかのぼる

          ①ヘルパークラスで定義を見てみる
            > $b2 = $form.findname("btn2")
            > $dp2 = [System.Windows.Controls.Button]::FontWeightProperty
            > [System.Windows.DependencyPropertyHelper]::GetValueSource($b2, $dp2) | fl

                BaseValueSource : Inherited <--★継承されていることは分かった
                IsExpression    : False
                IsAnimated      : False
                IsCoerced       : False
                IsCurrent       : False

          ②指定されている値を見てみる
            > $b2 = $form.findname("btn2")
            > $dp2 = [System.Windows.Controls.Button]::FontWeightProperty
            > $b2.getvalue($dp2)
              Bold            <--★見えた

          ③LogicalTreeをさかのぼって、「FontWeight」プロパティをローカルで
               セットしている場所を探す

             ・1つ親にさかのぼる
            > $b2 = $form.findname("btn2")
            > $dp2 = [System.Windows.Controls.Button]::FontWeightProperty
            > $StackPanel = $b2.Parent

            > [System.Windows.DependencyPropertyHelper]::GetValueSource(`
                                                        $StackPanel, $dp2).BaseValueSource
              Inherited <--★ここも継承されている

            ・もう1つ親にさかのぼる
            > $GroupBox = $stackPanel.parent
            > [System.Windows.DependencyPropertyHelper]::GetValueSource(`
                                                              $GroupBox, $dp2).BaseValueSource
              Local   <-- ★(あった!!)

    「inherit」の追っかけ方(その2:上からたどる)
 
        ==> ロジカル階層(木構造)をすべてたどるツールを作って、
               それをベースに探索・表示した例 (ツール自身は自作なので省略)

        探索・表示の結果

         >System.Windows.Window                              name=""
            FontWeight :  Normal  ( Default )
           >System.Windows.Controls.GroupBox                 name="myGroupBox"
               FontWeight :  Bold  ( Local )                      <--★(これ!!)
              string                                                                     name=""
             >System.Windows.Controls.StackPanel             name=""
                  FontWeight :  Bold  ( Inherited )             <--★
               >System.Windows.Controls.Button               name="Button1"
                     FontWeight :  Medium  ( Local )
                  string                                                             name=""
               >System.Windows.Controls.Button               name="Button2"
                     FontWeight :  Bold  ( Inherited )           <—★
                  string                                                              name=""
               >System.Windows.Controls.Button               name="Button3"
                     FontWeight :  Normal  ( Local )
                  string                                         name=""


サンプルの実行例
PowershellだけでWPF表示(Powershell3.0でも2.0でも稼働)
.Netframeworkは3.0以上が必要
WPFの約束としてPowershellはSTAモードで動く必要あり
以下コードを

  ①Powershellコンソールにコピペして実行
  ②ISEで実行する時は、すでにSTAモードなので最初の6行は不要

    注意:ブラウザによってはコピペで行頭に余分な空白が出来てしまうことあり
           C:\temp> □'@ # ← ここの行の行頭に空白あると動かない


(コード)
#-----------------------------------
if ($host.Version.Major -eq 3) {
     powershell.exe
} else {
     powershell.exe -version 2 -sta
}

$xaml_win1 = @'
<Window
        xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="250" Width="280"
        >

    <Window.Resources>
        <LinearGradientBrush x:Key="gradBrush" StartPoint="0,0" EndPoint="1,1">
            <GradientStop Color="SteelBlue" Offset="0" />
            <GradientStop Color="PowderBlue" Offset="1"/>
        </LinearGradientBrush>
    </Window.Resources>

    <GroupBox FontWeight="Bold" Name="myGroupBox">
        <GroupBox.Header>
            Buttons
        </GroupBox.Header>
            <StackPanel Background="{StaticResource gradBrush}" Name="sp">
                <TextBlock FontFamily="Arial Black" Margin="7"
                           Background="{StaticResource gradBrush}">
                           Some Buttons</TextBlock>
                <Button Height="40" Name="btn1" FontWeight="Bold"
                           Background="{StaticResource gradBrush}">
                           Button 1</Button>
                <Button Height="40" Name="btn2"
                           Background="{StaticResource gradBrush}">
                           Button 2</Button>
            </StackPanel>
    </GroupBox>

</Window>
'@

if ($host.Version.Major -eq 3) {
    Add-Type -assembly WindowsBase,PresentationCore,PresentationFramework,System.Xaml,System.xml
} else {
    Add-Type -assembly WindowsBase,PresentationCore,PresentationFramework
}

$form = [System.Windows.Markup.XamlReader]::Parse($xaml_win1)
[void]$Form.ShowDialog()
#-------------------------------------------------

2013年1月23日水曜日

依存関係プロパティ(その1)


依存関係プロパティ(DependecyProperty)について

依存関係プロパティは、「ほかの要素の値に依存してプロパティの値を決定する機構」
    以下にDependencyPropertyの取得方法(5つ方式)を示す

1.直接取得
    > [System.Windows.Controls.Control]::FontSizeProperty
    ( これでも同じ、 [System.Windows.Controls.Button]::FontSizeProperty)

                       ↓↓↓(同じものが見える)

  Name FontSize
  PropertyType System.Double
  OwnerType System.Windows.Documents.TextElement
  DefaultMetadata System.Windows.FrameworkPropertyMetadata
  ValidateValueCallback System.Windows.ValidateValueCallback
  GlobalIndex 21
  ReadOnly False

    > [System.Windows.Controls.Control]::FontSizeProperty
                   ↓↓↓(リターン)
        System.Windows.DependencyProperty

        「C#」的な定義は以下の通り
        > public static readonly DependencyProperty FontSizeProperty;


2.DependencyObjectクラスのメソッドで取得

    > [System.Windows.DependencyObject]::GetLocalValueEnumerator()
               ↓↓↓(リターン)
        System.Windows.LocalValueEnumerator

        すなわち、[System.Windows.LocalValueEntry]型として以下の
        4種のデータの配列が得られる

            ・WPF明示的に設定したDependencyProperty
            ・WPF明示的設定なAttached Property(区別つかず)
            ・WFP暗示的に設定されたDependencyProperty
            ・Xamlにより設定されたDependencyProperty

        得られないもの  ←  どうやってみるかは、別記事で…
           ・「CLR」なDependencyPropertyは見えない
           ・「inherit」なDependencyPropertyは見えない
               
        ちなみに、依存関係プロパティ・インスタンスからは、以下様にたどれる。
> [System.Windows.DependencyObject]::GetValue(System.Windows.DependencyProperty)
                       ↓↓↓(リターン)
                  System.Object
3.MarkupWriterクラスのメソッドで取得

> [System.Windows.Markup.Primitives.MarkupWriter]::GetMarkupObjectFor(System.Object)
            ↓↓↓(リターン)
       System.Windows.Markup.Primitives.MarkupObject

  得られたインスタンスを以下のように表示すると、
> [System.Windows.Markup.Primitives.ElementMarkupObject]::Properties

            以下のものが見える
            ・WPF明示的に設定したDependencyProperty
            ・WPF明示的設定なAttached Property(区別がつく)
            ・「CLR」なProperty

            得られないもの ← どうやってみるかは、別記事で…
            ・WFP暗示的に設定されたDependencyProperty
            ・Xamlにより設定されたDependencyProperty
            ・「inherit」なDependencyPropertyは見えない

4.DependencyPropertyDescriptorクラスのメソッドで取得

> [System.ComponentModel.DependencyPropertyDescriptor]::FromName(`
                                                  System.String, System.Type, System.Type)
                                                               ①                    ②                  ③
            ①DP名        文字列
            ②Owner型   DPをRegisterしたクラス型
            ③Target型   DPを参照するクラス型

                   ↓↓↓(リターン)
           System.ComponentModel.DependencyPropertyDescriptor

5.PresentationFrameworkアセンブリから一覧を得る

    以下で型の全一覧を取得し、そこからDPをすべて抽出する
    >   add-type -assembly PresentationFramework -PassThru |                                
    >   % { $_.GetFields() } |                                                              
    >   % { foreach ( $f in $_ ) { if ($f.FieldType.Name -eq "DependencyProperty") { $f } } } |
    >   ? { $_.name -ne "Property" } |                                                      
    >   % { $_.GetValue("") } |                                                              
    >   sort GlobalIndex |                                                                  
    >   get-unique                                                                          


依存関係プロパティを総合的に表示するツールを作ってみた。
    ツールの中身は、このブログの目的とは違うので省略

        利用結果の例
       > $form.findname("Button2") | dp2:
  Name DP Type Value base
  ============ ======== === ====
  IsMouseDirectlyOver Indirect,Xaml False Local
  IsKeyboardFocused Indirect,Xaml False Local
  Content WPF Direct Button2 Local
  IsMouseCaptured Indirect,Xaml False Local
  Name WPF Direct Button2 Local
  HasContent Indirect,Xaml True Local

実際動かして確認してみる。
PowershellだけでWPF表示(Powershell3.0でも2.0でも稼働)
.Netframeworkは3.0以上が必要
WPFの約束としてPowershellはSTAモードで動く必要あり
以下コードを
  ①Powershellコンソールにコピペして実行
  ②ISEで実行する時はすでにSTAモードなので適時修正して実行
    注意:ブラウザによってはコピペで行頭に余分な空白が出来てしまうことあり
           C:\temp> □'@   ← ここの行の行頭に空白あると動かない

image 
 

#-----------------------------------
if ($host.Version.Major -eq 3) {
     powershell.exe
} else {
     powershell.exe -version 2 -sta
}

$xaml = @'
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="InheritFont.Window1" Height="225" Width="180">

    <GroupBox FontWeight="Bold" Name="myGroupBox">
        <GroupBox.Header>
            Buttons
        </GroupBox.Header>
        <StackPanel>
            <Button Name="Button1" FontWeight="Medium">Button 1</Button>
            <Button Name="Button2">Button 2</Button>
            <Button Name="Button3" FontWeight="Normal">Button 3</Button>
        </StackPanel>
    </GroupBox>

</Window>
'@

$code = @'
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace MyButton
{
    public class EventTest
    {
        public GroupBox gb;

        public void subscribe(Button b)
        {
            b.Click += Button_Click1;
        }

        public void Button_Click1(object sender, RoutedEventArgs e)
        {
            if (gb.FontWeight == FontWeights.Normal)
            {
                gb.FontWeight = FontWeights.Bold;
            } else {
                gb.FontWeight = FontWeights.Normal;
            }
        }
    }
}
'@

if ($host.Version.Major -eq 3) {
    Add-Type $code -ReferencedAssemblies @("WindowsBase","PresentationCore","PresentationFramework","System.Xaml","System.xml")
} else {
    Add-Type $code -ReferencedAssemblies @("WindowsBase","PresentationCore","PresentationFramework")
}
$form = [System.Windows.Markup.XamlReader]::Parse($xaml)
$mb = New-Object MyButton.EventTest
$mb.gb = $form.findname("myGroupBox")
$mb.subscribe($form.findname("Button3"))
[void]$Form.ShowDialog()

 

 
1.直接取得

  > [System.Windows.Controls.Control]::FontWeightProperty
    (これでも同じ [System.Windows.Controls.Button]::FontWeightProperty)
                     ↓↓↓
    Name                         : FontWeight
    PropertyType              : System.Windows.FontWeight
    OwnerType                : System.Windows.Documents.TextElement
    DefaultMetadata         : System.Windows.FrameworkPropertyMetadata
    ValidateValueCallback :
    GlobalIndex               : 154
    ReadOnly                  : False

2.DependencyObjectクラスのメソッドで取得

  > $form.FindName("Button2").GetLocalValueEnumerator()

     Property                  Value
     --------                    -----
     Name                      Button2
     IsMouseDirectlyOver False
     IsMouseCaptured     False
     IsKeyboardFocused  False
     Content                  Button 2
     HasContent             True

3.MarkupWriterクラスのメソッドで取得

> [System.Windows.Markup.Primitives.MarkupWriter]::GetMarkupObjectFor($form.FindName("Button2")).Properties

            ↓↓↓(以下の2つ)
       ①DependencyProperty    : Content
       ②DependencyProperty    : Name

4.DependencyPropertyDescriptorクラスのメソッドを使って取得

> [System.ComponentModel.DependencyPropertyDescriptor]::FromName("FontWeight", [System.Windows.Controls.Button], [System.Windows.FrameworkElement] )
               ↓↓↓(以下のものが得られる)
    DependencyProperty          : FontWeight

5.PresentationFrameworkアセンブリから一覧を得る
     面倒なので省略

2013年1月6日日曜日

コンテンツ(ComboBox選択)



ListBox(アイテム選択)クラス

クラスの定義は以下の通り

            Module Name: PresentationFramework.dll

       System.Windows.Controls.ComboBox
         System.Windows.Controls.Primitives.Selector
           System.Windows.Controls.ItemsControl         <--これから派生されているのはListBoxと同じ
             System.Windows.Controls.Control                (ItemsとItemsSrouceを保持)
               System.Windows.FrameworkElement
                 System.Windows.UIElement
                   System.Windows.Media.Visual
                     System.Windows.DependencyObject
                       System.Windows.Threading.DispatcherObject
                         System.Object

どのアイテムが選択されているか?を知るには
    「SelectionBoxItem」プロパティにて知る

           System.Type : System.Windows.Controls.ComboBox

    >   [System.Windows.Controls.ComboBox]::System.Object get_SelectionBoxItem()
    >   [System.Windows.Controls.ComboBox]::System.Object SelectionBoxItem
    >   [System.Windows.Controls.ComboBox]::System.Windows.DependencyProperty SelectionBoxItemProperty


実際に使ってみる

  1. PowershellだけでWPF表示(Powershell3.0でも2.0でも稼働)
  2. .Netframeworkは3.0以上が必要
  3. WPFの約束としてPowershellはSTAモードで動く必要あり
  4. 以下コードを
      ①Powershellコンソールにコピペして実行
      ②ISEで実行する時はすでにSTAモードなので適時修正して実行
        注意:ブラウザによってはコピペで行頭に余分な空白が出来てしまうことあり
               C:\temp> □'@   ← ここの行の行頭に空白あると動かない 

 ComboBox(アイテム選択)の動作確認
#-------------------------------------------------------
if ($host.Version.Major -eq 3) {
    powershell.exe
} else {
    if ($host.Runspace.ApartmentState -eq "STA") {return}
    powershell.exe -version 2 -sta
}

$xaml_win = @'
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="ComboBox調査" Height="220" Width="250">

    <Canvas>
        <ComboBox Name="Combo1" SelectedIndex="0" Width="134">
            <ComboBoxItem>第1アイテム</ComboBoxItem>
            <ComboBoxItem>第2アイテム</ComboBoxItem>
            <ComboBoxItem>第3アイテム</ComboBoxItem>
            <ComboBoxItem>第4アイテム</ComboBoxItem>
            <ComboBoxItem>第5アイテム</ComboBoxItem>
        </ComboBox>
        <Button Name="Example" Padding="10,3" Canvas.Right="100" Canvas.Bottom="5">
            押下
        </Button>
    </Canvas>
</Window>
'@  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

$code = @'
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace MyButton
{
    public class comboClass
    {
        public ComboBox combo;
 
        public void subscribe(Button b)
        {
            b.Click += Button_Click;
        }

        public void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show( combo.SelectionBoxItem.ToString() + " が、選択されました", "通知");
        }
    }
}
'@  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

if ($host.Version.Major -eq 3) {
    Add-Type $code -ReferencedAssemblies @("WindowsBase","PresentationCore","PresentationFramework","system.xaml")
} else {
    Add-Type $code -ReferencedAssemblies @("WindowsBase","PresentationCore","PresentationFramework")
}
$form = [System.Windows.Markup.XamlReader]::Parse($xaml_win)
$m = new-object MyButton.comboClass
$m.subscribe($form.findname("Example"))
$m.combo = $form.findname("Combo1")
[void]$form.showdialog()
exit
#-------------------------------------------------------


コンテンツ(ListBox通知)


ListBox(アイテム選択通知)クラス

クラスの定義は以下の通り

        Module Name: PresentationFramework.dll

       System.Windows.Controls.ListBox
         System.Windows.Controls.Primitives.Selector
           System.Windows.Controls.ItemsControl         <--これから派生されている(ItemsとItemsSrouceを保持)
             System.Windows.Controls.Control
               System.Windows.FrameworkElement
                 System.Windows.UIElement
                   System.Windows.Media.Visual
                     System.Windows.DependencyObject
                       System.Windows.Threading.DispatcherObject
                         System.Object

アイテム選択の通知
    「SelectionChanged」イベント発生で知らせてくる。

    ちなみに、このイベントの定義場所は以下の通り

        >   (type: ListBox -s)[0].GetEvents() | ? name -EQ "SelectionChanged"

            MemberType       : Event
            Name             : SelectionChanged
            DeclaringType    : System.Windows.Controls.Primitives.Selector      <--★ここで定義
            ReflectedType    : System.Windows.Controls.ListBox
            MetadataToken    : 335544480
            Module           : PresentationFramework.dll
            Attributes       : None
AddMethod     : Void add_SelectionChanged(System.Windows.Controls.SelectionChangedEventHandler)
RemoveMethod: Void remove_SelectionChanged(System.Windows.Controls.SelectionChangedEventHandler)
            RaiseMethod      :
            EventHandlerType : System.Windows.Controls.SelectionChangedEventHandler
            IsSpecialName    : False
            IsMulticast      : True
            CustomAttributes : {[System.ComponentModel.CategoryAttribute("Behavior")]}

    補足(実際にはルーテッド・イベントとして定義)  <--後程...
        >   [System.Windows.EventManager]::GetRoutedEvents() | where-object { $_.name -eq "SelectionChanged" } | fl

            Name            : SelectionChanged  <--★こっち
            RoutingStrategy : Bubble
            HandlerType     : System.Windows.Controls.SelectionChangedEventHandler
            OwnerType       : System.Windows.Controls.Primitives.Selector

            Name            : SelectionChanged
            RoutingStrategy : Bubble
            HandlerType     : System.Windows.RoutedEventHandler
            OwnerType       : System.Windows.Controls.Primitives.TextBoxBase

実際に使ってみる

  1. PowershellだけでWPF表示(Powershell3.0でも2.0でも稼働)
  2. .Netframeworkは3.0以上が必要
  3. WPFの約束としてPowershellはSTAモードで動く必要あり
  4. 以下コードを
      ①Powershellコンソールにコピペして実行
      ②ISEで実行する時はすでにSTAモードなので適時修正して実行
        注意:ブラウザによってはコピペで行頭に余分な空白が出来てしまうことあり
               C:\temp> □'@   ← ここの行の行頭に空白あると動かない 

ListBox(アイテム選択通知)の動作確認

#-------------------------------------------------------
if ($host.Version.Major -eq 3) {
    powershell.exe
} else {
    if ($host.Runspace.ApartmentState -eq "STA") {return}
    powershell.exe -version 2 -sta
}

$xaml_win = @'
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="ListBox2調査" Height="220" Width="250">

    <StackPanel>
        <ListBox Name="lstbxWives" HorizontalAlignment="Left" Width="100">
            <ListBoxItem>瀬名姫</ListBoxItem>
            <ListBoxItem>濃姫</ListBoxItem>
            <ListBoxItem>ねね姫</ListBoxItem>
        </ListBox>
    </StackPanel>
</Window>
'@  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

$code = @'
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace MyButton
{
    public class lstbxButtonClass
    {
        public void subscribe(ListBox l)

        {
            l.SelectionChanged += lstbxWives_SelectionChanged;
        }

        private void lstbxWives_SelectionChanged( object sender, SelectionChangedEventArgs e )
        {
            ListBox lb = sender as ListBox;
            ListBoxItem lbi = lb.SelectedItem as ListBoxItem;
            MessageBox.Show( lbi.Content.ToString()+ " が、選択されました", "通知" );
        }
    }
}
'@  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

if ($host.Version.Major -eq 3) {
    Add-Type $code -ReferencedAssemblies @("WindowsBase","PresentationCore","PresentationFramework","system.xaml")
} else {
    Add-Type $code -ReferencedAssemblies @("WindowsBase","PresentationCore","PresentationFramework")
}
$form = [System.Windows.Markup.XamlReader]::Parse($xaml_win)
$m = new-object MyButton.lstbxButtonClass
$m.subscribe($form.findname("lstbxWives"))
[void]$form.showdialog()
exit
#-------------------------------------------------------

コンテンツ(ListBox:選択)


ListBox(アイテム選択)クラス

クラスの定義は以下の通り

        Module Name: PresentationFramework.dll

       System.Windows.Controls.ListBox
         System.Windows.Controls.Primitives.Selector
           System.Windows.Controls.ItemsControl         <--これから派生されている(ItemsとItemsSrouceを保持)
             System.Windows.Controls.Control
               System.Windows.FrameworkElement
                 System.Windows.UIElement
                   System.Windows.Media.Visual
                     System.Windows.DependencyObject
                       System.Windows.Threading.DispatcherObject
                         System.Object


実装にあたって2つの形式がある

    ①ListBoxItemとして保持する(ラップする)
    ②直接配列として保持する

アイテム選択
     SelectedItem、SelectedItemsプロパティにより実現

        単数選択モード時
        >   [System.Windows.Controls.Primitives.Selector]::System.Object get_SelectedItem()
        >   [System.Windows.Controls.Primitives.Selector]::Void set_SelectedItem(System.Object)
        >   [System.Windows.Controls.Primitives.Selector]::System.Object SelectedItem

        複数選択モード時
        >   [System.Windows.Controls.ListBox]::System.Collections.IList get_SelectedItems()
        >   [System.Windows.Controls.ListBox]::System.Collections.IList SelectedItems
        >   [System.Windows.Controls.ListBox]::System.Windows.DependencyProperty SelectedItemsProperty


        どのアイテムを選んでいるか等のIndex処理で利用
        >   [System.Windows.Controls.Primitives.Selector]::Int32 get_SelectedIndex()
        >   [System.Windows.Controls.Primitives.Selector]::Void set_SelectedIndex(Int32)
        >   [System.Windows.Controls.Primitives.Selector]::Int32 SelectedIndex



実際に使ってみる

  1. PowershellだけでWPF表示(Powershell3.0でも2.0でも稼働)
  2. .Netframeworkは3.0以上が必要
  3. WPFの約束としてPowershellはSTAモードで動く必要あり
  4. 以下コードを
      ①Powershellコンソールにコピペして実行
      ②ISEで実行する時はすでにSTAモードなので適時修正して実行
        注意:ブラウザによってはコピペで行頭に余分な空白が出来てしまうことあり
               C:\temp> □'@   ← ここの行の行頭に空白あると動かない 

 ListBox(アイテム選択)の動作確認

#-------------------------------------------------------
if ($host.Version.Major -eq 3) {
    powershell.exe
} else {
    if ($host.Runspace.ApartmentState -eq "STA") {return}
    powershell.exe -version 2 -sta
}

$xaml_win = @'
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="ListBox調査" Height="220" Width="250">

    <StackPanel>
        <ListBox Name="lstbxCats" HorizontalAlignment="Left" Width="100">
        <!--
        <ListBox Name="lstbxCats" HorizontalAlignment="Left" Width="100" SelectionMode="Multiple">
        -->
                <ListBoxItem>徳川家康</ListBoxItem>
                <ListBoxItem>織田信長</ListBoxItem>
                <ListBoxItem>豊臣秀吉</ListBoxItem>
        </ListBox>
        <Button Name="lstbxButton" HorizontalAlignment="Left" Padding="10,3" Margin="0,5">Enter</Button>
    </StackPanel>
</Window>
'@  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

$code = @'
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace MyButton
{
    public class lstbxButtonClass
    {
        public ListBox lstbxCats;
 
        public void subscribe(Button b, ListBox l)
        {
            b.Click += Button_Click;
            this.lstbxCats = l;
        }

        private void Button_Click( object sender, RoutedEventArgs e )
        {
            object obj = lstbxCats.SelectedItem;
            string selected = "";
            if ( obj == null )
            {
                selected = "アイテムは選択されていません";
            } else {
                selected = (string) ((ListBoxItem)obj).Content;
            }
            MessageBox.Show( selected, "Selected Item" );
        }
    }
}
'@  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

if ($host.Version.Major -eq 3) {
    Add-Type $code -ReferencedAssemblies @("WindowsBase","PresentationCore","PresentationFramework","system.xaml")
} else {
    Add-Type $code -ReferencedAssemblies @("WindowsBase","PresentationCore","PresentationFramework")
}
$form = [System.Windows.Markup.XamlReader]::Parse($xaml_win)
$m = new-object MyButton.lstbxButtonClass
$m.subscribe($form.findname("lstbxButton"), $form.findname("lstbxCats"))
[void]$form.showdialog()
exit


コンテンツ(ListBox基本)


ListBoxクラス

クラスの定義は以下の通り

        Module Name: PresentationFramework.dll

  System.Windows.Controls.ListBox
    System.Windows.Controls.Primitives.Selector
      System.Windows.Controls.ItemsControl <--これから派生されている(ItemsとItemsSrouceを保持)
        System.Windows.Controls.Control
          System.Windows.FrameworkElement
            System.Windows.UIElement
              System.Windows.Media.Visual
                System.Windows.DependencyObject
                  System.Windows.Threading.DispatcherObject
                    System.Object


実装にあたって2つの形式がある

①ListBoxItemとして保持する(ラップする)
②直接配列として保持する


実際に使ってみる

  1. PowershellだけでWPF表示(Powershell3.0でも2.0でも稼働)
  2. .Netframeworkは3.0以上が必要
  3. WPFの約束としてPowershellはSTAモードで動く必要あり
  4. 以下コードを
      ①Powershellコンソールにコピペして実行
      ②ISEで実行する時はすでにSTAモードなので適時修正して実行
        注意:ブラウザによってはコピペで行頭に余分な空白が出来てしまうことあり
               C:\temp> □'@   ← ここの行の行頭に空白あると動かない 

ListBoxItemにラップする形式と直接配列保存の形式
 ListBoxの動作確認
#-------------------------------------------------------
if ($host.Version.Major -eq 3) {
    powershell.exe
} else {
    if ($host.Runspace.ApartmentState -eq "STA") {return}
    powershell.exe -version 2 -sta
}

$xaml_win = @'
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Expander調査" Height="220" Width="250">

<ListBox>
   <ListBoxItem>徳川家康</ListBoxItem>
   <ListBoxItem>織田信長</ListBoxItem>
   <ListBoxItem>豊臣秀吉</ListBoxItem>
</ListBox>
<!--
<ListBox>
<TextBlock>徳川家康</TextBlock>
<TextBlock>織田信長</TextBlock>
<Button>豊臣秀吉</Button>
</ListBox>
-->
</Window>
'@  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

#-------------------------------------------------------
if ($host.Version.Major -eq 3) {
Add-Type -AssemblyName WindowsBase,PresentationCore,PresentationFramework,system.xml,System.Xaml
} else {
Add-Type -AssemblyName WindowsBase,PresentationCore,PresentationFramework,system.xml
}
$form = [System.Windows.Markup.XamlReader]::Parse($xaml_win)
[void]$form.showdialog()
exit
#-------------------------------------------------------

保管データの確認

  • 形式1(ListBoxItemでカプセル)

> 0..2 | % { $form.Content.Items[$_].content }
徳川家康
織田信長
豊臣秀吉

  • 形式2(直接的に配列保管)

> 0..2 | % { $form.content.items[$_].gettype() } | ft Name -AutoSize
Name
----
TextBlock
TextBlock
Button

コンテンツ(Expander)

HeaderedContentControlクラス

クラス定義は、

    Module Name: PresentationFramework.dll

System.Windows.Controls.HeaderedContentControl
 System.Windows.Controls.ContentControl         <--これの拡張
   System.Windows.Controls.Control
     System.Windows.FrameworkElement
       System.Windows.UIElement
         System.Windows.Media.Visual
           System.Windows.DependencyObject
             System.Windows.Threading.DispatcherObject
               System.Object

 このクラスはコンテンツを保持するプロパティを2つ持つ

    「ContentControl」クラスが元々持っているもの
        >   [System.Windows.Controls.ContentControl]::System.Object get_Content()
        >   [System.Windows.Controls.ContentControl]::Void set_Content(System.Object)
        >   [System.Windows.Controls.ContentControl]::System.Object Content
        >   [System.Windows.Controls.ContentControl]::System.Windows.DependencyProperty ContentProperty

    「HearderedCotentControl」クラスで追加されたもの(上記Contentのタイトル表記)
        >   [System.Windows.Controls.HeaderedContentControl]::Void set_Header(System.Object)
        >   [System.Windows.Controls.HeaderedContentControl]::Boolean get_HasHeader()
        >   [System.Windows.Controls.HeaderedContentControl]::System.Object Header
   >   [System.Windows.Controls.HeaderedContentControl]::System.Windows.DependencyProperty HeaderProperty


「HearderedCotentControl」から派生するクラスの一覧は?

        IsPublic IsSerial Name     BaseType
        -------- -------- ----     --------
        True     False    GroupBox System.Windows.Controls.HeaderedContentControl
        True     False    Expander System.Windows.Controls.HeaderedContentControl
        True     False    TabItem  System.Windows.Controls.HeaderedContentControl


Expanderクラスについて

    以下の2つを同時に実現
    ・1つのコンテンツを保持する
    ・コンテンツを表示/非表示を切り替えられる


実際に使ってみる

  1. PowershellだけでWPF表示(Powershell3.0でも2.0でも稼働)
  2. .Netframeworkは3.0以上が必要
  3. WPFの約束としてPowershellはSTAモードで動く必要あり
  4. 以下コードを
      ①Powershellコンソールにコピペして実行
      ②ISEで実行する時はすでにSTAモードなので適時修正して実行
        注意:ブラウザによってはコピペで行頭に余分な空白が出来てしまうことあり
               C:\temp> □'@   ← ここの行の行頭に空白あると動かない 

折りたたんだ状態と表示した状態
Expanderの動作確認
#-------------------------------------------------------
if ($host.Version.Major -eq 3) {
    powershell.exe
} else {
    if ($host.Runspace.ApartmentState -eq "STA") {return}
    powershell.exe -version 2 -sta
}

$xaml_win = @'
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Expander調査" Height="220" Width="250">

<Grid>
<Expander Header="Important Buttons">
<StackPanel>
<Button>Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
</StackPanel>
</Expander>
</Grid>
</Window>
'@  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

#-------------------------------------------------------
if ($host.Version.Major -eq 3) {
Add-Type -AssemblyName WindowsBase,PresentationCore,PresentationFramework,system.xml,System.Xaml
} else {
Add-Type -AssemblyName WindowsBase,PresentationCore,PresentationFramework,system.xml
}
$form = [System.Windows.Markup.XamlReader]::Parse($xaml_win)
[void]$form.showdialog()
exit

コンテンツ(GroupBox)




HeaderedContentControlクラス

クラス定義は、

    Module Name: PresentationFramework.dll

System.Windows.Controls.HeaderedContentControl
 System.Windows.Controls.ContentControl         <--これの拡張
   System.Windows.Controls.Control
     System.Windows.FrameworkElement
       System.Windows.UIElement
         System.Windows.Media.Visual
           System.Windows.DependencyObject
             System.Windows.Threading.DispatcherObject
               System.Object

 このクラスはコンテンツを保持するプロパティを2つ持つ

    「ContentControl」クラスが元々持っているもの
        >   [System.Windows.Controls.ContentControl]::System.Object get_Content()
        >   [System.Windows.Controls.ContentControl]::Void set_Content(System.Object)
        >   [System.Windows.Controls.ContentControl]::System.Object Content
        >   [System.Windows.Controls.ContentControl]::System.Windows.DependencyProperty ContentProperty

    「HearderedCotentControl」クラスで追加されたもの(上記Contentのタイトル表記)
        >   [System.Windows.Controls.HeaderedContentControl]::Void set_Header(System.Object)
        >   [System.Windows.Controls.HeaderedContentControl]::Boolean get_HasHeader()
        >   [System.Windows.Controls.HeaderedContentControl]::System.Object Header
   >   [System.Windows.Controls.HeaderedContentControl]::System.Windows.DependencyProperty HeaderProperty

「HearderedCotentControl」から派生するクラスの一覧は?

        IsPublic IsSerial Name     BaseType
        -------- -------- ----     --------
        True     False    GroupBox System.Windows.Controls.HeaderedContentControl
        True     False    Expander System.Windows.Controls.HeaderedContentControl
        True     False    TabItem  System.Windows.Controls.HeaderedContentControl


GroupBoxについて   <--以下の2つを同時に実現

  • 1つのコンテンツを保持する
  • そのコンテンツのヘッダー情報を保持すること

実際に使ってみる

  1. PowershellだけでWPF表示(Powershell3.0でも2.0でも稼働)
  2. .Netframeworkは3.0以上が必要
  3. WPFの約束としてPowershellはSTAモードで動く必要あり
  4. 以下コードを
      ①Powershellコンソールにコピペして実行
      ②ISEで実行する時はすでにSTAモードなので適時修正して実行
        注意:ブラウザによってはコピペで行頭に余分な空白が出来てしまうことあり
               C:\temp> □'@   ← ここの行の行頭に空白あると動かない 

文字ヘッダーと画像ヘッダーの例
GroupBoxの動作確認
#-------------------------------------------------------
if ($host.Version.Major -eq 3) {
    powershell.exe
} else {
    if ($host.Runspace.ApartmentState -eq "STA") {return}
    powershell.exe -version 2 -sta
}

$xaml_win = @'
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="GroupBox調査" Height="220" Width="250">

    <GroupBox Header="Grouped Things" Margin="5">
        <StackPanel>
            <Image Margin="3" HorizontalAlignment="Left" Height="50" Source="c:\temp\work\photo.jpg">
            </Image>
            <Button Margin="3">ボタン1</Button>
            <Button Margin="3">ボタン2</Button>
        </StackPanel>
    </GroupBox>
    <!--
    <GroupBox Margin="5">
        <GroupBox.Header>
        <Image Margin="3" HorizontalAlignment="Left" Height="50" Source="c:\temp\work\photo.jpg">
        </Image>
        </GroupBox.Header>
        <StackPanel>
            <Button Margin="3">ボタン1</Button>
            <Button Margin="3">ボタン2</Button>
        </StackPanel>
    </GroupBox>
    -->
</Window>
'@  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

#-------------------------------------------------------
if ($host.Version.Major -eq 3) {
Add-Type -AssemblyName WindowsBase,PresentationCore,PresentationFramework,system.xml,System.Xaml
} else {
Add-Type -AssemblyName WindowsBase,PresentationCore,PresentationFramework,system.xml
}
$form = [System.Windows.Markup.XamlReader]::Parse($xaml_win)
[void]$form.showdialog()
exit



2013年1月5日土曜日

コンテンツ(Window2)


ContentControlクラス    単一エレメントを保持することができるContentと呼ばれるプロパティが含まれている
                                (自分の子供として単一エレメントを保持する)
       クラス定義は、

                Module Name: PresentationFramework.dll

          System.Windows.Controls.ContentControl   ←  これ
            System.Windows.Controls.Control
              System.Windows.FrameworkElement
                System.Windows.UIElement
                  System.Windows.Media.Visual
                    System.Windows.DependencyObject
                      System.Windows.Threading.DispatcherObject
                        System.Object

         単一エレメントを保持する「Content」プロパティは

                >   [System.Windows.Controls.ContentControl]::System.Object get_Content()
                >   [System.Windows.Controls.ContentControl]::Void set_Content(System.Object)
                >   [System.Windows.Controls.ContentControl]::System.Object Content
                >   [System.Windows.Controls.ContentControl]::System.Windows.DependencyProperty ContentProperty

        「ContentControl」から派生するクラスの一覧は?

        IsPublic IsSerial Name                           BaseType
        -------- -------- ----                                   --------
        True     False    Window                          System.Windows.Controls.ContentControl
        True     False    Label                             System.Windows.Controls.ContentControl
        True     False    ScrollViewer                    System.Windows.Controls.ContentControl
        True     False    ButtonBase                     System.Windows.Controls.ContentControl
        True     False    ListBoxItem                     System.Windows.Controls.ContentControl
        True     False    HeaderedContentControl System.Windows.Controls.ContentControl
        True     False    Frame                            System.Windows.Controls.ContentControl
        True     False    GroupItem                       System.Windows.Controls.ContentControl
        True     False    StatusBarItem                 System.Windows.Controls.ContentControl
        True     False    ToolTip                           System.Windows.Controls.ContentControl
        True     False    UserControl                     System.Windows.Controls.ContentControl


Window.ShowDialog()について

    >   Bool ShowDialog()   Windowを表示する。Closeするまで処理は戻ってこない


実際に使ってみる

  1. PowershellだけでWPF表示(Powershell3.0でも2.0でも稼働)
  2. .Netframeworkは3.0以上が必要
  3. WPFの約束としてPowershellはSTAモードで動く必要あり
  4. 以下コードを
      ①Powershellコンソールにコピペして実行
      ②ISEで実行する時はすでにSTAモードなので適時修正して実行
        注意:ブラウザによってはコピペで行頭に余分な空白が出来てしまうことあり
               C:\temp> □'@   ← ここの行の行頭に空白あると動かない 

Window.ShowDialog()の動作確認
---------------------------------------------
if ($host.Version.Major -eq 3) {
    powershell.exe
} else {
    if ($host.Runspace.ApartmentState -eq "STA") {return}
    powershell.exe -version 2 -sta
}

$xaml_win = @'
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="ダイアログ調査" Height="180" Width="250">
    <Grid>
      <Button Name="myButton1" VerticalAlignment="Top">
         ダイアログ作成</Button>
   </Grid>
</Window>
'@  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

@'
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Dialogウインドウ" Height="180" Width="250">
    <StackPanel>
      <TextBlock Padding="10">ボタン押下</TextBlock>
      <Button IsCancel="True" Name="MyButton2Cancel">Cancel</Button>
      <Button IsDefault="True" Name="MyButton2Ok">Ok</Button>
    </StackPanel>
</Window>
'@ > c:\temp\test.xaml  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

$code = @'
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

namespace DialogBoxes
{
   public class DialogCtrl
   {
      public void subscribe(Button b)
      {
        b.Click += Button_Click;
      }

      private Window xReaderLoad()
      {
        FileStream fs = new FileStream("/temp/test.xaml", FileMode.Open, FileAccess.Read);
        return (Window) XamlReader.Load(fs);
      }

      private void Button_Click( object sender, RoutedEventArgs e )
      {
         Window win = xReaderLoad();
         Button b = (Button)win.FindName("MyButton2Ok");
         b.Click += Button_Click1;
         win.ShowDialog();
      }

      private void Button_Click1( object sender, RoutedEventArgs e )
      {
         bool? DialogResult = true;
         System.Console.WriteLine("Dialog結果コード:" + DialogResult);
      }
   }
}
'@  # <--ブラウザによっては、コピペ時に行頭に空白出来る。空白削除する必要あり

if ($host.Version.Major -eq 3) {
    Add-Type $code -ReferencedAssemblies @("WindowsBase","PresentationCore","PresentationFramework","system.xaml")
} else {
    Add-Type $code -ReferencedAssemblies @("WindowsBase","PresentationCore","PresentationFramework")
}
$form = [System.Windows.Markup.XamlReader]::Parse($xaml_win)
$dlg = new-object DialogBoxes.DialogCtrl
$dlg.subscribe($form.FindName("myButton1"))
$form.showdialog()
exit