2013年1月27日日曜日

依存関係プロパティ(その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()
#-------------------------------------------------

0 件のコメント:

コメントを投稿