dragan10

依存性プロパティ-優先順位

2008-10-10 01:17:33

今回で依存性プロパティについては終わりにします。最後に、あまり意識することはない割にとても重要なことの一つ、依存性プロパティの優先順位について話をしましょう。もとより依存性プロパティは一つ以上の情報源(たとえばリソース、データバインディング、アニメーションなど)から最終的な値が決まるものなので、これはとても重要な話なのです。

ルールはがっちり決まっていて、単純明快です・・・

 

アニメーションが最優先

もしその値に関係しているアニメーションがあるなら、その値が他のすべての値よりも優先されます。

 

アニメーションをのぞけば、ローカル値が最優先

アニメーションがないのなら、ローカル値を使えば他のすべての値に優先されます。

 

アニメーションもローカル値もないならテンプレート/スタイル

アニメーションもローカル値もないなら、テンプレートからの値が使われます。もしテンプレートの値もなければ、スタイルの値が使われます。

 

以上のいずれもないならデフォルト値

もし以上のどれにも当てはまらないなら、その型のデフォルト値が使われます。

デフォルト値

この最後の規則があるため、すべての型はデフォルトの見かけを持たなければならず、したがってgeneric.xamlに書き込みをする必要があります。カスタムコントロールの値の中に、アニメーションにも影響されず、ローカルの値も持たず、テンプレートやスタイルからも値をもらっていないものがある場合、依存性プロパティのシステムは、generic.xamlの中のデフォルト値を探して使うからです。

最初のアプリケーション

ここまでで、最初のアプリケーションのコードを調べる準備ができました。覚えておられると思いますが、ソリューションには三つのプロジェクトがあります。CustomControl.csには自分たちで書いたコントロールの見かけに関するロジックを宣言してありますが、最終的には通常のロジック(イベントハンドラなど)も宣言することになるでしょう。現時点では、リストはとても単純です:

 using System.Windows.Controls;
 
 namespace ClassLibrary
 {
    public class CustomControl : Control
    {
       public CustomControl()
       {
          DefaultStyleKey = typeof( CustomControl );
       }
    }
 }

デフォルトの表示スタイルを実現するのにもっともシンプルなロジックです。一方、generic.xamlに書かれているのをご記憶かと思いますが、デフォルトのスタイルはThemesフォルダにあります。

 
 <ResourceDictionary
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:controls="clr-namespace:ClassLibrary"
     xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     mc:Ignorable="d">
     <Style TargetType="controls:CustomControl">
         <Setter Property="Template" >
             <Setter.Value>
                 <ControlTemplate TargetType="controls:CustomControl">
                     <Grid x:Name="LayoutRoot">
                         <Ellipse x:Name="Core"
                             Width="75" Height="75"
                             Stroke="Blue" StrokeThickness="2" >
                             <Ellipse.Fill>
                                 <RadialGradientBrush>
                                     <GradientStop Color="#FFE0E1F0" Offset="0.004"/>
                                     <GradientStop Color="#FF8080B1" Offset="1"/>
                                     <GradientStop Color="#FF05052B" Offset="0.911"/>
                                 </RadialGradientBrush>
                             </Ellipse.Fill>
                         </Ellipse>
                     </Grid>
                 </ControlTemplate>
             </Setter.Value>
         </Setter>
     </Style>
 </ResourceDictionary>
    

忘れずに、このファイルのBuildActionプロパティの値をResourceに設定してください。

Page.xamlは作成したカスタムコントロールのインスタンスと、TextBlockのインスタンスを生成します。

<UserControl x:Class="SkinnableCustomControl.Page"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:Controls="clr-namespace:ClassLibrary;assembly=ClassLibrary"              
     Width="400" Height="300">
     
     <Grid x:Name="LayoutRoot" Background="White">
         <Grid.RowDefinitions>
             <RowDefinition Height=".7*" />
             <RowDefinition Height=".3*" />
         </Grid.RowDefinitions>
         <Controls:CustomControl x:Name="CustomCtrl" Grid.Row="0" />
         
         <TextBlock Text="Skinnable Custom Control"
                    FontFamily="Georgia" FontSize="18"
                    HorizontalAlignment="Center" Grid.Row="1" />
     </Grid>
 </UserControl>

実行すると、(テキストブロックと共に)カスタムコントロールが描かれます。


この時点では、このコントロールはマウスオーバーのようなビジュアル・イベントには反応しませんし、クリックを処理するロジックもありません。ですが、デフォルトの見かけは持っていて、自分自身を描画することができます。(最小限とはいえ)パーツ&状態モデルにしたがっているので、現時点で不足しているものをおぎなうのも、もう単純な作業だけですみます。

それではまた。

 
-jesse


※このエントリは ブロガーにより投稿されたものです。朝日インタラクティブ および ZDNet Japan編集部の見解・意向を示すものではありません。
  • 新着記事
  • 特集
  • ブログ