| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

Silverlight リソースとスタイル

提供: MyMemoWiki
2020年2月15日 (土) 08:38時点におけるPiroto (トーク | 投稿記録)による版
ナビゲーションに移動 検索に移動

Silverlight UI フレームワーク

Silverlight | C Sharp |

概要

  • コントロール・テンプレートは、スタイルの中で利用されることが多い
  • スタイルはほぼ間違いなく、リソースとして定義される
  • つまり、リソース、スタイル、コントロール・テンプレートの3つをまとめて使用することが多い

リソース

  • WPF UIフレームワークでは、リソース・ディクショナリにオブジェクトを追加しておくことで、そのオブジェクトをリソースとして、XAML上で簡単に再利用できる。

単純なリソースの例

  • 実行時に生成される、SolidColorBrushオブジェクトが1つで済むため、メモリを節約
個別に指定
<StackPanel>
    <Ellipse Fill="Blue" Height="150" />
    <Ellipse Fill="Blue" Height="150" />
</StackPanel>
リソース・ディクショナリを使用
<StackPanel>
    <StackPanel.Resources>
        <SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
    </StackPanel.Resources>
    <Ellipse Fill="{StaticResource BlueBrush}" Height="150" />
    <Ellipse Fill="{StaticResource BlueBrush}" Height="150" />
</StackPanel>

リソースの種類

  • 追加先のリソース・ディクショナリの場所により、イミディエイト・リソースと、アプリケーション・リソースの2種類に分けられる
種類 概要 備考
イミディエイト・リソース FrameworkElementオブジェクトのResourcesプロパティ(ResourcesDictionary型)に宣言されたリソース FrameworkElementはUIElementの派生クラス。すべてのUI要素は、これを継承しているため、自身のResourcesプロパティにリソースを持つことができる。リソースの宣言要素と、その子要素から参照できる。
アプリケーション・リソース ApplicationオブジェクトのResourcesプロパティ(ResourceDictionary型)に宣言されたリソース アプリケーションの実装と管理で共通に使用される機能を提供。標準的なWPF/Silverlightのプロジェクトテンプレートでは、App.xamlファイルとその分離コードで使用されている。通常は、<Application>要素のResourceプロパティに宣言されたリソースが、アプリケーション・リソースとなり、どこかれでも参照できる

リソース・キー

  • リソース・ディクショナリの各リソースはキーによって識別されるため、x:Key属性を使用して、各リソースに対し、リソース・キーを割り当てておく必要がある。
  • 通常文字列が使用されるが、一部機能においてはオブジェクトが使用されることがある。

静的リソース参照

  • 多くの場合、リソースの参照には、StaticResourceマークアップ拡張機能を使用した、静的リソース参照が使用される。
具体例
<Ellipse Fill="{StaticResource BlueBrush}"/>

<blockquote>WPFでは、StaticResourceExtensionクラスのパラメータに、BlueBrushというキーを指定するのと同意となるが、Silverlight では、XAML専用となっており、StaticResourceExtensionクラスは存在しない</blockquote>

リソース検索

  • リソースの検索順
  1. イミディエイト・リソース
    1. リソース参照元
    2. 親要素
  2. アプリケーション・リソース

スタイル

スタイルの機能

  • FrameworkElementクラスがもつStyleプロパティにStyleオブジェクトを設定するという方法で使用する。
  • Resourcesプロパティと同様、ほぼすべてのUI要素で使用できる
プロパティ属性構文
<Ellipse Fill="Blue" Height="80" Width="160"/>
スタイルを使って書き換え
  • 同じプロパティがある場合、最後に宣言されたものが有効
  • スタイルを利用するより、直接設定したプロパティが優先
<Ellipse>
    <Ellipse.Style>
        <Style TargetType="Ellipse">
            <Setter Property="Fill" Value="Blue" />
            <Setter Property="Height" Value="80" />
            <Setter Property="Width" Value="160" />
        </Style>
    </Ellipse.Style>
</Ellipse>

スタイルの共有

  • リソースとしてリソース・ディクショナリに定義し、複数のUI要素で共有し、初めて意味を持つ機能となる。
StackPanelのリソースに登録し、共有する例
<StackPanel>
    <StackPanel.Resources>
        <Style x:Key="EllipseStyle" TargetType="Ellipse">
            <Setter Property="Fill" Value="Blue" />
            <Setter Property="Height" Value="80" />
            <Setter Property="Width" Value="160" />
        </Style>
    </StackPanel.Resources>
    <Ellipse Style="{StaticResource EllipseStyle}" />
    <Ellipse Style="{StaticResource EllipseStyle}" />
</StackPanel>

<blockquote>派生元のクラスが共通で、そのクラスに存在するプロパティに限定されれば、異なるクラス感でも同じスタイルを共有できる。</blockquote>

スタイルの継承

  • スタイルは継承元となるスタイルを、BasedOn プロパティに設定することで継承可能。
<StackPanel>
    <StackPanel.Resources>
        <Style x:Key="EllipseBaseStyle" TargetType="Ellipse">
            <Setter Property="Fill" Value="Blue" />
            <Setter Property="Height" Value="80" />
            <Setter Property="Width" Value="160" />
        </Style>
        <Style x:Key="EllipseStyle" TargetType="Ellipse"
               BasedOn="{StaticResource EllipseBaseStyle}">
            <Setter Property="Stroke" Value="Yellow"/>
            <Setter Property="StrokeThickness" Value="10"/>
        </Style>
    </StackPanel.Resources>

    <Ellipse Style="{StaticResource EllipseStyle}" />
    <Ellipse Style="{StaticResource EllipseStyle}" />
</StackPanel>

暗黙的にスタイルを適用

  • x:Key を設定せずに TargetType プロパティに 型に設定すると、x:Key が暗黙的に設定されます。
  • x:Key 値を指定すると、Style がすべての要素に自動的には適用されなくなります。
<StackPanel>
    <StackPanel.Resources>
        <Style TargetType="Ellipse">
            <Setter Property="Fill" Value="Blue" />
            <Setter Property="Height" Value="80" />
            <Setter Property="Width" Value="160" />
        </Style>
    </StackPanel.Resources>
    <Ellipse />
    <Ellipse />
</StackPanel>

コントロール・テンプレート

  • Win32でのオーナードローに替わるもの
  • 見た目の変更もプロパティの設定だけで比較的簡単に変更できる様になっている
  • Templateプロパティを利用しビジュアル構造を再定義できる

コントロール・テンプレートの内容を確認する手段

  • MSDNライブラリを参照
  • Silverlight「コントロールのスタイルとテンプレート」|http://msdn.microsoft.com/ja-jp/library/cc278075(VS.95).aspx]
  • Expression Blendの[コントロールのパーツ(テンプレート)の編集]-[コピーの編集]機能を利用
  • XamlWriterクラスのSaveメソッドを使用し、実行時にコードからTemplateプロパティの内容をシリアライズ(WPF)

TemplateBinding

  • コントロールのプロパティと、コントロール・テンプレート内の要素のプロパティとをバインドする必要がある
角丸ボタンを作成する例
<StackPanel>
    <StackPanel.Resources>
        <ControlTemplate x:Key="ButtonTemplate" TargetType="Button">
            <Border Background="{TemplateBinding Background}" CornerRadius="30" Padding="10">
                <TextBlock Text="{TemplateBinding Content}"
                               Foreground="White"
                               VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Border>
        </ControlTemplate>
    </StackPanel.Resources>
    <Button Content="Test1" Background="LightBlue"
            Template="{StaticResource ButtonTemplate}" Margin="30" />
    <Button Content="Test2" Background="Blue"
            Template="{StaticResource ButtonTemplate}" Margin="30" />
</StackPanel>

ContentPresenter要素

  • Buttonコントロールは文字列に限らず、画像やUI要素といったさまざまなオブジェクトをコンテンツとして表示できるContentControlタイプのコントロール
  • ButtonコントロールのContentプロパティには、Image要素やPanel要素といった文字列以外のオブジェクトを設定することができる

<blockquote>ContentプロパティがTextBlockのTextプロパティとバインディングしていたのでは、そのようなオブジェクトを表示させることはできない。文字列以外のコンテンツが設定された場合でも、そのコンテンツをきちんと表示させるためには、そのための専用の要素である「ContentPresenter要素」を使用する必要がある</blockquote>