印刷用ページ       送信     
クリックして評価とフィードバックをお寄せください
MSDN
MSDN ライブラリ
テクニカルドキュメント
Windows Vista
Windows Presentation Foundation
 Windows Presentation Foundation ガイド...
Windows Presentation Foundation ガイド ツアー

Tim Sneath

Microsoft Corporation

September 2005

日本語版最終更新日 2006 年 6 月 8 日

適用対象 :

   WinFX Runtime Components

概要 : 新しいグラフィック サブシステム、Windows Presentation Foundation (以前のコード名 "Avalon") の概要とそれを取り巻く状況について紹介します。開発者向けのこのリリースに含まれるアーキテクチャと主要コンポーネントをご覧ください。

WinFX Runtime Components をダウンロードします。

目次

はじめに
Windows Presentation Foundation
レイアウト : 画面上への要素の配置
XAML
グラフィックおよびテキスト サービス
テキスト
スタイルとデータ バインディング
データ バインディング
ドキュメント サービス
アプリケーション モデル
ハイパフォーマンスなアプリケーションの作成
相互運用性および移行
まとめ
参照先

はじめに

過去 10 年間、アプリケーション開発のモデルには、従来の "スマート クライアント" をインストールしたアプリケーションと Web ベースのアプリケーションの 2 つの流れがあり、アプリケーション開発の覇権を争ってきました。これら 2 つのモデルはどちらも、開発にあたって、他方の環境では当然と考えられている機能が犠牲になります。Web アプリケーションは、多くのユーザーが利用でき、展開が容易で単純ですが、その代わりにステート情報がなく、展開モデルが複雑で、AJAX などの技術の再認識が活かされていないために、プラットフォーム エクスペリエンスの統合が不十分です。その一方、Windows の世界では、オフラインで動作し、クライアント ハードウェアを十分に活用するアプリケーションが簡単に作成できますが、Web アプリケーションで利用される展開の容易さや無数のマークアップ ツールのサポートは望めません。今日では、スタンドアロンかつブラウザベースのアプリケーションを利用でき、展開が容易な上に多数のツールをサポートし、さらにプラットフォームと強固に統合されたクライアント アプリケーション モデルが求められているのです。

Windows ユーザー エクスペリエンス形成の中核となるグラフィカル サブシステム (USER32 と GDI のライブラリ) が、最初のバージョンの Windows で登場してから今や 20 年になろうとしています。もちろん、USER32 も GDI もその間、長足の進化と発展を遂げており、あらゆる領域で多くの新サービスや新機能が導入されてきました。また近年、ビデオ カードのグラフィック機能が飛躍的に向上しており、これをフルに活用する Direct3D などの新しいプレゼンテーション テクノロジも登場しています。しかし、現在の主流のアプリケーションは、これらのグラフィック カードが本来実現可能なエクスペリエンスを提供していません。

Windows Presentation Foundation

Windows Presentation Foundation (コード名 "Avalon") は、ユーザー インターフェイス、2D および 3D グラフィックス、ドキュメント、メディアに統一的にアプローチする Windows の新しい戦略的グラフィック サブシステムです。.NET Framework を基盤として構築され、Direct3D を利用してベクトルベースのレンダリングを行うことで、高度な表現力を備えたあらゆる種類のアプリケーションを構築するための強力なソリューションを提供します。さらに、"ツール作成の容易性" と柔軟性を実現する宣言型プログラミング モデルを提供しているので、設計者は、開発プロセスで重要な役割を果たすことができます。

表 1 Windows Presentation Foundation のサービス

基本サービス

XAML、プロパティ システム、入力およびイベンティング、アクセシビリティ

メディア サービス

2D、3D、オーディオ、ビデオ、テキスト、イメージング、アニメーション、特殊効果、合成エンジン

ドキュメント サービス

XPS ドキュメント、Open Packaging Conventions

ユーザー インターフェイス サービス

アプリケーション サービス、展開、制御、レイアウト、データ バインディング

Windows Presentation Foundation の設計原則は、次のカテゴリに分類されます。

  • 統合

    Windows Presentation Foundation は、表 1 に示すサービスをすべて備えた統合 API を提供します。今日の開発者は、無数の異なるテクノロジや API の中から、2D グラフィックス (GDI または GDI+)、ユーザー インターフェイス (USER32 または Windows Forms)、メディア (DirectShow)、3D (Direct3D または OpenGL) など、場合に応じて選択する必要があります。Windows Presentation Foundation は、これらのサービスをすべて備えた 1 つのモデルを提供するので、単一のアプリケーション内で、コンテンツをシームレスに統合できます。これにより、2D、3D、テキスト コンテンツのいずれの場合でも、同じ構造でアニメーション、データ バインディング、およびスタイルが行えます。

  • ベクトル   グラフィックス

    「はじめに」で説明したように、Windows Presentation Foundation は、最近の PC システムに搭載された強力な GPU (Graphical Processing Units) をフルに活用します。その中心となるのはベクトルベースの合成エンジンで、これによってすべての出力が個別のマシンの解像度に合わせて調整されます。レンダリング アーキテクチャでは、すべての出力が Direct3D を経由します。ハードウェアに DirectX 7 以降を実装したビデオ カードでは、出力のレンダリングに可能な限り GPU が使用されます。ハードウェアによるレンダリングができない場合、フォールバックとしてソフトウェア レンダリングが可能です。さらに、浮動小数点論理ピクセル システムと 32 ビット ARGB カラー サポートにより、高 DPI ディスプレイなどの将来のテクノロジの要請に対応するリッチな色再現性に富んだエクスペリエンスが可能になります。

  • 宣言型プログラミ

    Windows Presentation Foundation では、XAML (eXtensible Application Markup Language) という XML ベースの言語が採用され、これを使用して入れ子になったオブジェクト階層のインスタンス化とデータの挿入を行います。XAML は Windows Presentation Foundation だけで使用されているわけではありませんが、本質的には、UI の定義や構築などの作業に適した言語です。XAML で設計すると、動的ワークフローのシナリオでは、アプリケーションは実行時に UI ロジックを解析、操作できます。重要な点として、Windows Presentation Foundation で実現された XAML/分離コード モデルでは、設計者と開発者は Expression Interactive Designer などのツール、および ZAM 3D や Mobiform Aurora などのサードパーティの専門ツールを使用して、クライアント アプリケーションを共同で設計、開発できます。

  • 展開の容易さ

    Windows Presentation Foundation は、スタンドアロン アプリケーションと Web ブラウザ アプリケーションの両方をサポートしているので、両方の展開モデルの長所を利用できます。Web ブラウザ アプリケーションは、Internet Explorer の中から、1 つのウィンドウ全体を使用して、またはインライン フレームの中で実行できます。また Web アプリケーション特有の展開の容易さを持ちながら、クライアント マシンを危険なアプリケーションから保護する、部分信頼のサンドボックス内での動作が可能です。さらに、ローカル クライアント ハードウェアの性能を活用したり、3D やメディア サービスを使用して、現時点で最も優れた Web エクスペリエンスを実現できます。また、スタンドアロン アプリケーションを ClickOnce や MSI テクノロジ経由でローカルにインストールし、そのプラットフォームに完全にアクセスすることもできます。

  • ドキュメント   ライフスタイル

    Windows Presentation Foundation では、新しいドキュメントと印刷のテクノロジが採用されています。ローカル ストアにデータを残す必要があるアプリケーションは、Open Packaging Conventions という、Office 12 と共有され、重要なプロパティとカスタム メタデータ、デジタル署名と権利管理機能をサポートする Zip ベースのパッケージング仕様を利用できます。アプリケーションがインストールされていないマシンも含め、複数のマシン間でコラボレーションのためのドキュメントを共有する場合は、XML Paper Specification によってビジュアル要素を印刷可能で移植可能な型式に固定できます。

図 1 のアーキテクチャ図は、Windows Presentation Foundation の主なコンポーネントを示しています (四角の大きさは、各コンポーネントの重要性とは関係ありません)。

wpf101_01.gif
図 1 Windows Presentation Foundation アーキテクチャ


最上位では、Presentation Framework がマネージ API を提供し、これによって基盤となる機能が完全に利用できるようになります。Windows Presentation Foundation で開発を行う場合、大部分は、このレイヤのみで作業を行います。フレームワークには、多くの標準コントロール (Button、Label、Menu など)、レイアウト パネル、2D と 3D のグラフィックスおよびテキスト プリミティブ、イメージング効果、メディア、アニメーション、ドキュメント サービスのサポート、および GDI、DirectX Windows Forms/GDI+ との相互運用性のサポートなどが含まれています。

Windows Presentation Foundation の中心は、ビジュアル システムです。Windows Presentation Foundation のほとんどの要素は、基本ビジュアル クラスから派生されます。ビジュアル システムは、すべてのデータを合成し、画面出力を生成します。ここでビデオ、オーディオ、2D、3D、アニメーションが統合され、テキスト レイアウト サービスが提供されます。アーキテクチャ モデルの下位部分は合成エンジン上に構成され、透明レイヤからウィンドウ領域の無効化まですべてを考慮した上で、ビジュアル ツリーを画面にレンダリングします。

Windows Presentation Foundation で行われるレンダリングは、すべて Direct3D 経由で処理されます (ただし、Windows Vista ハードウェア ロゴ プログラムでは、DirectX 9 レベルの CPU が必須)。より多くのグラフィック処理を GPU で行うことにより、CPU を他の作業に振り分けられるので、パフォーマンスを向上させながらグラフィックの品質が高まります。これらの利点は、3D の世界だけではなく、2D グラフィックスも同じサービスを活用できます。GDI は、レガシ要素との統合目的以外には Windows Presentation Foundation 内で使用されることはありません。Windows Vista 搭載のマシンでは、新しいディスプレイ ドライバ モデルによって、メディア重視のアプリケーション用に、高度なパフォーマンス特性を持つ優れた出力が実現されます。

レイアウト : 画面上への要素の配置

ユーザー インターフェイス サブシステムの基盤となるサービスの 1 つがレイアウト、つまり、ウィンドウ内での要素の配置です。Windows Presentation Foundation のレイアウト システムでは、コンテンツに応じて最適化され、データ、スタイル、コントロールの操作性に優れた、柔軟で拡張性に富んだモデルがサポートされます。

Win32 をはじめとする従来のアプリケーション プラットフォームでは、レイアウトという概念がほとんどありません。コントロールは、キャンバスの (x,y) 座標上に配置され、開発者は、ウィンドウのサイズ変更とディスプレイの DPI 設定を考慮して、原点とすべての要素の座標を決定して手動で指定する必要があります。これに対して Windows Presentation Foundation では、レイアウトを複数の方法で実装でき、コンテンツに応じたサイズ調整、およびウィンドウ内でのコントロールと項目の位置管理が可能です。

Windows Presentation Foundation では、ほとんどすべての要素が、他の要素のホストとして使用できます。たとえば、次のように、ボタンに画像を含めることができます。

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" >
   <Button Width="260" Height="200" >
      <Image Source="C:\WINDOWS\Web\Wallpaper\follow.jpg" />
   </Button>
</Window>

wpf101_02.gif

また Windows Presentation Foundation には、子要素のサイズと位置を制御し、制限する 5 つのレイアウト パネル、Canvas、DockPanel、StackPanel、Grid、WrapPanel があります。

注意   SDK には、XAML を検証するための XamlPad という優れたツールが用意されています。XamlPad は、ユーザーが編集しているコードの基本的なエラー レポートと WYSIWYG プレビュー ウィンドウを備えています。

レイアウト パネル

Canvas を使用すると、現在の GDI や GDI+ の機能に似た、(x,y) 座標軸上の配置が行えます。また、追加されたプロパティを使用して項目の位置を制御することもできます。以下はその例です。

<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
   <Canvas Background="silver" Margin="20">
      <Button Canvas.Top="30" Canvas.Left="50">Hello world!</Button>
   </Canvas>
</Border>

この例では、Canvas.Top と Canvas.Left は、Canvas クラスのプロパティであり、Button に適用されてボタンの位置を制御します。

wpf101_03.gif

DockPanel では、正確な (x,y) の配置を考慮せずに項目を配置できます。

<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
   <DockPanel Background="silver" Margin="20">
      <Menu DockPanel.Dock="Top">
         <MenuItem Header="File" />
         <MenuItem Header="Edit" />
      </Menu>
      <TreeView>
         <TreeViewItem Header="root1">
            <TreeViewItem Header="child" />
         </TreeViewItem>
         <TreeViewItem Header="root2"/>
      </TreeView>
      <ListBox>
         <ListBoxItem>listBoxItem1</ListBoxItem>
         <ListBoxItem>listBoxItem2</ListBoxItem>
      </ListBox>
   </DockPanel>
</Border>

wpf101_04.gif

StackPanel は、コンテンツを左から右、または上から下へと配置するスタック モデルを提供します。

<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
   <StackPanel Orientation="Horizontal" Background="silver" Margin="20" LayoutTransform="scale 2">
      <Button Height="30" Margin="5">OK</Button>
      <Button Height="30">Cancel</Button>
   </StackPanel>
</Border>

wpf101_05.gif

Grid は、行/グリッドを配置するためのモデルを提供します。

<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
   <Grid Background="silver" Margin="20" LayoutTransform="scale 3">
   <Button Width="200" Height="60" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="20" >Hello</Button>
   </Grid>
</Border>

グリッド内には、列と行を定義でき、それによって幅と高さが設定できます。列と行は、絶対値 (x ピクセル幅) に設定することも、絶対値を使用して設定した残りのスペースをアスタリスクによって割り当てることもできます。あるいは、係数を設定してスペースの割り当て方法を決定することもできます。以下はその例です。

<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
   <Grid ShowGridLines="true">
    <Grid.ColumnDefinitions">
          <ColumnDefinition Width="30" /">
          <ColumnDefinition Width="2*" /">
          <ColumnDefinition Width="*" /">
    </Grid.ColumnDefinitions">
      <Grid.RowDefinitions">
          <RowDefinition /">
      </Grid.RowDefinitions">
      <Button Grid.Column="1" Margin="10"">Hello world!"</Button">
   </Grid">
</Border">

SharedSizeGroup では、複数オブジェクトに同一のサイズを指定できます。たとえば、通常はサイズが異なる 2 つのボタンに対してこのプロパティを指定すると、これらのボタンの幅が同じになります。以下はその例です。

<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Grid ShowGridLines="true" IsSharedSizeScope="true" Height="80">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Buttons" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Buttons" />
</Grif.CloumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Column="1" Margin="10">OK</Button>
<Button Grid.Column="2" Margin="10">A very long cancel button</Button>
</Grid>
</Border>

WrapPanel は、エクスプローラ ウィンドウの右側のウィンドウ枠をモデリングし、項目が現在の行の行末に達すると、新しい行に折り返します。以下はその例です。

<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
   <WrapPanel Background="Silver" Margin="10">
<Button /> <Button /> <Button /> <Button /> <Button /> <Button /> <Button /> <Button
/> <Button /> <Button /> <Button /> <Button /> <Button /> <Button /> <Button />
<Button /> <Button /> <Button /> <Button /> <Button /> <Button /> <Button /> <Button
/> <Button /> <Button /> <Button /> <Button />
   </WrapPanel>
</Border>

これらのレイアウト パネルは、その子要素のレイアウトも行います。つまり、コンテンツ、整列方法、余白のサイズと形状を定義できます。パネルの子には、TextBox や Button などの要素を使用することも、または別のパネルを子として使用することもできます。たとえば、DockPanel の中に StackPanel を含めることができます。

項目のサイズは、それに含まれているコンテンツに応じて調整されます。このことは重要です。なぜなら、たとえば、同じ意味の文でも、言語によってテキストの長さが違いますが、パネルを使用すれば、アプリケーションをローカライズしても、アプリケーション レイアウトを調整し直す必要がないからです。整列方法は HorizontalAlignment/VerticalAlignment プロパティを使用して、余白は Margin プロパティを指定します。

ScrollViewer では、子のコンテンツにスクロール バーを設定します。利用可能なスペースからコンテンツがオーバーフローすると、スクロール バーが表示され、ユーザーがコンテンツ領域を移動できるようになります。以下はその例です。

<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" >
   <ScrollViewer>
      <TextBlock FontSize="20" TextWrapping="Wrap" FontFamily="Global User Interface">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce posuere volutpat erat.
Praesent imperdiet nibh nec pede. Mauris quis orci. Maecenas luctus, risus tempus
dapibus mollis, magna metus convallis nunc, eget pulvinar eros ipsum consectetuer dui.
      </TextBlock>
   </ScrollViewer>
</Border>

wpf101_06.gif

ViewBox では、ScrollViewer とは逆に、コンテンツのサイズが親パネルに収まるように制限されます。これにより、一種の自動ズーム効果が得られます。

<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
   <Viewbox>
      <TextBlock FontFamily="Global User Interface">
         Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
      </TextBlock>
   </Viewbox>
</Border>

wpf101_07.gif

wpf101_08.gif

レイアウト プロトコルとは、ネゴシエーションの形態を取る反復的なプロセスです。これにより、配置する要素に関する要求に基づき、すべての要素に対して "十分な" スペースを確保できます。まず、測定プロセスが実行され、親が子に対してサイズを問い合わせ、子はそれに対して DesiredSize で応答します。次に、配置プロセスが実行され、親が ActualSize プロパティを使用して子のサイズを指定します。計算時には、Double.PositiveInfinity という特殊な値が "コンテンツに合わせてサイズを調整する" という意味になります。この値を扱う場合は、パネルの MeasureOverride と ArrangeOverride の 2 つの要素をオーバーライドします。

XAML

グラフィック機能を詳細に見ていく前に、Windows Presentation Foundation における XAML の使用方法について簡単に説明します。ここまで、XAML を使用したサンプルをいくつか示しました。ここで重要となるのは、XAML が単に UI コードを簡単に書くための言語ではなく、Windows Presentation Foundation の必須コンポーネントだということです。XAML でできることは、C# や Visual Basic などの .NET 言語でも行うことができます。

上のレイアウト パネルの説明で示した最初の例を見てみましょう。

<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
   <Canvas Background="silver" Margin="20">
      <Button Canvas.Top="30" Canvas.Left="50">Hello world!</Button>
   </Canvas>
</Border>

Visual Basic では、次のように記述できます。

Dim myBorder As New Border, myCanvas As New Canvas, myButton As New Button
With myCanvas
   .Background = Brushes.Silver
   .Margin = New Thickness(20)
End With
With myButton
   .Content = "Hello World"
End With
myCanvas.Children.Add(myButton)
Canvas.SetTop(myButton, 30.0)
Canvas.SetLeft(myButton, 50.0)
myBorder.Child = myCanvas
or in C# as:
Border b = new Border();
Canvas c = new Canvas();
Button btn = new Button();
c.Background = Brushes.Silver;
c.Margin = new Thickness(20);
btn.Content = "Hello World";
c.Children.Add(btn);
Canvas.SetTop(btn, 30.0D);
Canvas.SetLeft(btn, 50.0D);
b.Child = c;
this.Content = b;

この簡単な例だけでも、XAML がオブジェクト構築のための一貫した、整理された階層モデルを持っており、現在の Windows Forms で必要とされているコードの非表示領域が XAML では不要であることがわかります。

しかし、XAML は、.NET Framework 言語に対する完全な代替言語ではありません。XML マークアップ言語を、高度な構造とフロー制御ロジックの代わりに利用することはできません。また XAML は、従来型のプログラミング言語とともに使用するように設計されています。XAML をコンパイルすると、部分クラス (1 つのクラス定義を複数のファイルに分離するための .NET Framework 2.0 の新機能) 内のバイナリ表現にコンパイルされます。そのクラスの残りの半分は、言語を自由に選択して実装します。たとえば、Visual Basic では、次のようになります。

Partial Public Class Window1
    Inherits Window
...
End Class
and in C#:
public partial class Window1 : Window { ... }

作成したコードからは、XAML のすべての名前付き要素にアクセスできます。この動作は、コード内で名前付き要素を宣言した場合と同様です。このようなアクセスができるのは、コードが同じクラスの一部であるためです。

XAML を使用することによって、モデルとビューの分離など、優れたアーキテクチャ原則がサポートされます。開発者と設計者が、特殊用途のツール (たとえば、3D デザイン ツール、設計者用ツール、開発ツール、ハイエンドのタイポグラフィ ツール) を使用して共同作業を行うことができ、XAML で出力される限り、それらのツールを組み合わせて高度な UI を構築できます。

グラフィックおよびテキスト サービス

「はじめに」で述べたように、現在の Windows グラフィックス プラットフォーム (GDI) は、約 20 年の歴史があります。過去数年間、3D の分野で大きな変革がありましたが、GDI の開発者はこれまでその恩恵をほとんど受けていません。今日のグラフィックス ハードウェアの進歩は、3D パイプラインが中心であり、Windows Presentation Foundation は、最近の PC が持つグラフィック機能を十分に活用するために、従来の 2D ベースのテクノロジに代わって戦略的に展開するためのテクノロジです。2D、3D、テキスト、画像およびビデオなどの異なるグラフィックス要素が、すべて同じパイプラインを経由します。

Windows Presentation Foundation は、アプリケーションとコンテンツのためのメインストリーム グラフィックス サービスを提供します。また新しいグラフィックス カードで一般的にサポートされている 3D ハードウェアを活用するアプリケーション モデルを提供します。Windows Presentation Foundation では、ベクトルベースのコンテンツがさらに重視されています。また論理ピクセルにマップされ、高 DPI 画面をサポートする仮想ピクセルを使用することにより、解像度への依存から解放されます。ネイティブの座標系は、倍精度浮動小数点数型に基づいています。新しいレンダリング モデルの副次的な効果として、補足の処理を行わなくても、画像変換を適用できます (たとえば、任意のコンテンツにぼかし効果や倍率を適用できます)。Windows Presentation Foundation は、大きなグラフィックス エコシステムの中の統合されたコンポーネントでもあるので、たとえば、新しい Windows Vista ディスプレイ ドライバ モデルを活用したり、プリント モデルと機能を共有したり、ターミナル サービス経由で高度の再現性を備えたリモーティングを実現できます。

wpf101_09.gif

図 3 North Face の店内設置用エクスプローラ プロトタイプ

図 3 は、PDC 2005 カンファレンスで展示された臨場感あふれるアプリケーション エクスペリエンスを示しています。表示されているものは、すべて 3D です。テキストは、サブピクセル ClearType を利用しています。ビデオ コントロールの作成にあたっては、合成によって異なるコンテンツ タイプが統合され、対話形式のエクスペリエンスが実現されています。

Windows Presentation Foundation での開発には、複数のレイヤがあります。マネージ コードについては、ほとんどの開発者がフレームワーク レベルで作業し、System.Windows.Shapes、System.Windows.Media などの名前空間のオブジェクトを使用するか、そうでなければ既存のグラフィックス バックエンドの代わりとして、下位のビジュアル レイヤ レベルで作業します (レイアウトやデータ バインディングなどのサービスを利用せずに描画プリミティブにアクセスする)。イメージング コーデックや効果などのサービスへのアクセスや拡張には、アンマネージ コードも使用できます。

2D グラフィックス

Shapes は、開発に使用できる最も基本的な 2D グラフィック要素で、ブラシ、ペン、図形、変換などが含まれています。すべてのプロパティは、依存プロパティです。つまり、アニメーション効果やデータ バインディングなどを適用できます。

For example:
<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Slider Name="WidthSlider" Maximum="200" Minimum="10" />
<Rectangle Height="100" Width="{Binding ElementName=WidthSlider, Path=Value}" >
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint "1,1">
<LinerGradientBrush.GradientStops>
<GradientStop Color="#FF3366FF" Offset="0" />
<GradientStop Color="#FFFFFFFF" Offset="1" />
</LinearGradientBrush.GradientSteps>
</LinearGradientBrush>
</RectAngle.Fill>
</Rectangle>
</StackPanel>
 

wpf101_10.gif

 

wpf101_11.gif

(データ バインディングについては、後で詳しく説明します)

このような単純な作業でも、Win32 では再描画を管理する必要があるので、コードの量が大幅に増加します。四角形などの形状が FrameworkElement から派生すること、つまりそれらの形状がレイアウト システムに参加していることにも注意してください。このため、以下のコードでは、四角のサイズが大きくなるにつれ、残りのスペースを埋める楕円が小さくなります。

<DockPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
   <Slider Name="WidthSlider" DockPanel.Dock="Top" Maximum="200" Minimum="10" />
   <Rectangle Fill="Red" Width="{Binding ElementName=WidthSlider, Path=Value}" />
   <Ellipse Fill="Blue" />
</DockPanel>

Brushes は、図形の塗りつぶしに使用します。ブラシの種類は数多く用意されていますが、よく使われるのは、おそらくソリッド、グラデーション、タイルでしょう。開発のほとんどを XAML で行う場合は、既定でソリッド ブラシを使用することも可能です。たとえば前の例で、四角と楕円には、どちらも緑のソリッド ブラシが使用されています。これは、名前付き文字列をその色のブラシに変換する簡略な "ミニ言語" が、XAML に用意されているからです。

グラデーション ブラシは、微妙なフェードやドラマチックな効果を出すために使用します。目の錯覚を利用した画像を例として説明します。

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"">
<!-- 奇妙な目の錯覚が起きる特殊効果。この画像をしばらく見つめてください。やがて画像が動き出します。
最初のグラデーションが、Black から LightBlue で停止します。しばらくすると、
グラデーションが全部消えたように見えます。 -->
   <Rectangle>
      <Rectangle.Fill>
         <LinearGradientBrush StartPoint="0.0, 0.0" EndPoint="0.01, 0.03"
                              SpreadMethod="Reflect">
            <LinearGradientBrush.GradientStops>
               <GradientStop Color="Black" Offset="0.3" />
               <GradientStop Color="Silver" Offset="0.8" />
            </LinearGradientBrush.GradientStops>
         </LinearGradientBrush>
      </Rectangle.Fill>
   </Rectangle>
</Grid>

ImageBrush は、コーデック (たとえば、PNG、JPEG、GIF) がサポートするあらゆる画像をブラシとして使用できるタイル ブラシです。他のタイル ブラシと同様、ImageBrush のコンテンツは、並べて表示したり、伸縮して表示することができます。また、変形を使用した画像の傾き、回転、伸縮、変換も可能です。

最も強力なブラシの 1 つが VisualBrush です。これは、あらゆるビジュアル オブジェクトがコンテンツとなる TileBrush です。VisualBrush を使用すると、ライブの "セカンダリ" 表現が可能です (たとえば、すでに開いているウィンドウに、ライブのサムネイルを表示するツールチップなど)。またはブラシ自体にビジュアル コンテンツを埋め込み、それを何らかの方法で変形することもできます。

<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
      <StackPanel Name="reflectedPanel" Orientation="Horizontal">
         <TextBox Width="300" FontSize="48">Reflections...</TextBox>
         <Button Content="OK" Margin="2" />
      </StackPanel>
      <StackPanel Height="{Binding Path=(StackPanel.ActualHeight),
                                         ElementName=reflectedPanel}">
         <StackPanel.Background>
            <VisualBrush Stretch="None" Opacity="0.75"
              AlignmentX="Left" AlignmentY="Top"
              Visual="{Binding ElementName=reflectedPanel}">
               <VisualBrush.RelativeTransform>
                  <TransformGroup>
                     <MatrixTransform Matrix="1,0,0,-1,0,0" />
                     <TranslateTransform Y="1" />
                  </TransformGroup>
               </VisualBrush.RelativeTransform>
            </VisualBrush>
         </StackPanel.Background>
         <StackPanel.OpacityMask>
            <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
               <LinearGradientBrush.GradientStops>
                  <GradientStop Color="#FF000000" Offset="0.0" />
                  <GradientStop Color="#00000000" Offset="0.8" />
               </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
         </StackPanel.OpacityMask>
      </StackPanel>
   </StackPanel>

wpf101_12.gif

SDK には、このほかにも VisualBrush の使用方法のサンプルが用意されています。

特定のアートワークをアプリケーション全体で使用する場合、ベクトルレンダリング命令を表す drawing を使用できます。ベクトルレンダリング命令は、一度宣言すれば、何度でも再使用できます。その代表的な例として、ベクトル グラフィックスやアイコンがあります。drawing は、ビジュアル レイヤで動作する軽快なオブジェクトです。このオブジェクトは、レイアウト システムに参加しないので、パフォーマンスが重視される場合に利用できます。

Windows Presentation Foundation が備えている便利なクラスに、描画とブラシを 1 つに組み合わせる DrawingBrush クラスがあります。これは、2D または 3D の表面に適用できるタイル ブラシであり、静的ベクトル リソースを入力して他の場所で使用できます (たとえば、ベクトルの塗りつぶしを入力して、UI の背景に使用できます)。

3D グラフィックス

Windows Presentation Foundation が備えている便利なクラスに、描画とブラシを 1 つに組み合わせる DrawingBrush クラスがあります。これは、2D または 3D の表面に適用できるタイル ブラシであり、静的ベクトル リソースを入力して他の場所で使用できます (たとえば、ベクトルの塗りつぶしを入力して、UI の背景に使用できます)。

中心的なオブジェクトの 1 つが Viewport3D という、3D コンテンツをホストする 2D 要素です。これはモデル、照明、カメラを表します。Model3D は、2D の描画に類似した 3D オブジェクトであり、特定の 3D 図形を表します。素材は、テクスチャや照明の特性として表されます。テキスト、ビデオ、形状、描画など、コンテンツはすべて、素材内でブラシとして使用できます。

モデルを手動でオーサリングするのは面倒な作業です。これを解決する 1 つの方法は Electric Rain の ZAM3D などのツールを使用することです。また 3D は、データ ビジュアライゼーションのためのユーザー インターフェイス (3D グラフの作成、2D コンテンツと複数の 2D データ セットのスーパーポジショニングの間の移行) でも自然に使用できます。

wpf101_13.gif

図 4 ZAM3D でレンダリングした Channel 9 のマスコット

ただし、Windows Presentation Foundation の 3D API は、DirectX に代わるものではありません。リアルな 3D ゲーム、大規模な 3D アプリケーション (たとえば、CAD)、および汎用的な GPU シナリオには、Direct3D を使用してください。Windows Presentation Foundation は、Direct3D の "手動"/"スティックシフト" モードとまったく同一と考えられます。

イメージング

Windows Presentation Foundation は、コーデックのライブラリ経由で、ほとんどの一般的な画像型式をサポートします。アプリケーションに画像を埋め込むには、次の XAML を使用するだけです。

<Image Width="200" Source="sampleImages\apple.jpg" />

画像は基本的には四角ですが、それを幾何学的な図形で切り取ることができます。

<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Margin="20">
<Image
  Source="C:\WINDOWS\Web\Wallpaper\follow.jpg"
  Width="200" Height="150" HorizontalAlignment="Left">
  <Image.Clip>
    <EllipseGeometry
      RadiusX="100"
      RadiusY="75"
      Center="100,75"/>
  </Image.Clip>
</Image>
</Border>

ImageBrush を使用して、画像をテクスチャとして適用できます。以下はその例です。

<Ellipse Stroke="Purple" StrokeThickness="5.0">
    <Ellipse.Fill>
      <ImageBrush
         ImageSource="table-bowl.jpg"
         TileMode="Tile"
         Viewport="0,0,.3,.3" />
    </Ellipse.Fill>
  </Ellipse>

ImageSource は、ベクトル画像 (DrawingImage) またはビットマップ画像 (BitmapSource) の基本クラスです。

Windows Presentation Foundation は、インプレース アップデートを使用することにより、メタデータに関して豊富で拡張可能なサポートを提供します (JPEG の EXIF データを変更しても、ファイル全体を読み書きする必要がありません)。また、わかりやすいクエリ機能もあり、たとえば、次のようなことが可能です。

BitmapMetadata m = ((BitmapMetaData)myImage.Metadata); // get metadata from a JPEG 
string focalLength = m.GetQuery("System.Photo.FocalLength");
string exposure = m.GetQuery("System.Photo.ExposureTime"); 

またはキーが設定されていないメタデータを (TIFF から) 取得します。

string value123 = m.GetQuery("/ifd/{uint=123}"); // from a TIFF

メディア

フレームワークの要素レベルに、ビデオとオーディオをサポートする MediaElement というオブジェクトがあります。このオブジェクトは、タイムラインとクロックを使用して制御できます (再生、一時停止、シークなど)。Windows Presentation Foundation は、WMV、MPEG、および一部の AVI をサポートします。また将来のビルドでは、メディアをアニメーションと同期できるようになります。

特殊効果

ビットマップ画像の特殊効果では BitmapSource を使用し、BitmapSource を返します。一般的な使用方法では、ビットマップの特殊効果をビジュアル ツリーのビジュアル オブジェクトに適用します。この PDC ビルドでは、ぼかし効果と影付きの 2 つの特殊効果がサポートされており、将来、RTM までにはさらに多くの効果がサポートされる予定です。重要なのは、イメージの効果が拡張可能であることです。したがって、独自のイメージの効果を作成して、他のユーザーがそれを適用できます。

以下は、使用方法の例です。

<StackPanel.BitmapEffect>
 <BlurBitmapEffect Radius="8" />
 </StackPanel.BitmapEffect>

アニメーション

依存プロパティはすべて、どの Windows Presentation Foundation オブジェクト上でもアニメーション化できます。アニメーションはオブジェクト レベルで実行されますが、調整を容易にするために、アニメーションをストーリーボード レベルで使用する方が一般的です。アニメーションはフレームベースではなく時間ベースなので、時間的解像度には依存しません (つまり 1 秒間にレンダリングされるフレーム数は問題ではないので、アニメーションの速度は、システム パフォーマンスに依存しません)。

ストーリーボードは、プロパティではなく、トリガによって動作します。トリガはイベント ドリブン (Button.Click など) であり、1 つ以上の動作 (ColorAnimation や DoubleAnimation など) を制御できます。つまり、複数の要素のプロパティが使用されます。以下は、アニメーションを実行する例です。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Ellipse Width="200" Height="200">
    <Ellipse.Triggers>
      <EventTrigger RoutedEvent="Rectangle.Loaded">
        <BeginStoryboard>
          <Storyboard>
            <ColorAnimation
                From="Blue"
                To="Red"
                Duration="00:00:01"
                RepeatBehavior="Forever"
                AutoReverse="true"
                Storyboard.TargetName="gradientStop"
                Storyboard.TargetProperty="Color" />
          </Storyboard>
        </BeginStoryboard>
      </EventTrigger>
    </Ellipse.Triggers>
    <Ellipse.Fill>
<!-- アニメーション効果付きグラデーション -->
      <LinearGradientBrush x:Name="brush" EndPoint="1,1">
        <LinearGradientBrush.GradientStops>
          <GradientStopCollection>
            <GradientStop Color="Blue" Offset="0" />
            <GradientStop x:Name="gradientStop" Offset="0.5" />
            <GradientStop Color="Red" Offset="1" />
          </GradientStopCollection>
        </LinearGradientBrush.GradientStops>
      </LinearGradientBrush>
    </Ellipse.Fill>
  </Ellipse>
</Page>

この簡単な例では、左上から右下にかけて丸が移動するのにつれ画面の色が塗り変わり、それが終わると今度は逆向きの塗り替えが始まります。上のコードの中央で、GradientStop が青から赤にアニメーション化され、次にその逆が実行されます。

アニメーションは複雑なトピックで、このホワイト ペーパーで説明できる概要以上の事項が数多くあります。コードからストーリーボードを使用する方法のサンプルと詳細については、SDK のドキュメントを参照してください。

テキスト

Windows Presentation Foundation では、ClearType を使用した次世代のテキスト レンダリングが導入され、コンピュータ ディスプレイでテキストをさらに読みやすくするための数々の新技術が搭載されています。

Windows Presentation Foundation の ClearType には、特に次の 3 つの新機能が用意されています。

  • サブピクセル ポジショニング

  • 自然なアドバンス幅

  • Y 方向のアンチエイリアス

Windows 3.1 に含まれていた “白黒” の TrueType フォントの多く (たとえば、Times New Roman や Arial) では、自然なアドバンス幅を変更して文字の均整を整えるために、多くのグリフにヒントが追加されていました。アドバンス幅は、通常、±2 ピクセル単位で変更されました。白黒のピクセルの解像度が低い場合、読みやすさを確保するためには、文字の均整などが文字幅の正確さよりもはるかに重要になります。ClearType では、幅 (横) 方向の高解像度が実現されているので、グリフの均整とアドバンス幅の正確さが両立します。GDI は、解像度は高いのですが、グリフの幅を整数ピクセルで表現するという制約のため、すべての幅が近似ピクセル値に丸められます。

マイクロソフトでは GDI のシステムですべてのフォントに ClearType を使用することを目標としているため、ClearType on の幅を ClearType off の幅と同じにする必要がありました (この試みは、フォント スムージングでも行いました)。この動作を実現するためには、アドバンス幅を白黒と同じに設定する、互換幅と呼ばれるモードを GDI に追加する必要があります。このために、グリフに小さなエラーが生じます。残念なことに、このエラーのためにグリフの形状が認識可能な程度に歪み、グリフ サイズが小さくなるほど、ガンマ設定の誤りが大きな問題となります (Windows XP PowerToy に含まれている ClearType Tuner によって緩和できます)。

GDI では、互換幅と非互換幅のいずれかを選択できます。互換幅では、多少の誤りはあっても、白黒の場合やフォント スムージングの場合とまったく同じ幅を作成できます。非互換幅は、"自然幅" とも呼ばれ、Windows XP SP1 で使用できます。このモードでは高品質の ClearType が利用できますが、GDI に含まれているため、ピクセル値が整数に限られています。

Windows Presentation Foundation は、サブピクセル ポジションの ClearType を使用します。このため、ClearType が持つ完全な正確さを、画面上で再現できます。このオプションを使用すると、グリフの始点と終了の両方が、任意のピクセル位置に設定できます。これは特にカーニングと組み合わせると、非常に高品質な形状を画面に表示できます。高品質のスペーシングは、画面上に美しいテキストを表示するための重要な要素です。サブピクセル ポジショニングでは、コントラストが若干損なわれますが、優れたスペーシングがこれを補います。この高精度のスペーシングによって、テキストをデバイスに依存しない方法で配置できます。

最後に、Y 方向のアンチエイリアスによって、垂直軸の文字グリフの端が滑らかになります。この軸の RGB サブピクセルは利用できませんが、それでもテキスト レンダリングの制度を大幅に高めます。

Windows Presentation Foundation におけるすべてのテキスト レンダリングでは、合成、フィルタ、ブレンドを使用して CPU の作業負荷を軽減するため、適切なグラフィック カードが使用されていれば、ハードウェアによる高速な処理を実現できます。Windows Presentation Foundation でテキストのサポートが向上していることは、特に東アジア地域のフォントを使用するユーザーにとっては、注目に値することです。これらのフォントでは、これまで ClearType がサポートされておらず、プラットフォームを十分に活用できませんでした。

GDI レンダリングを搭載した Windows XP

 

wpf101_14.gif

Windows Presentation Foundation

 

wpf101_15.gif

また Windows Presentation Foundation は、分数、任意または文脈に応じた合字、小さいフォントの大文字、アンティーク文字の数字など、多くの新しい OpenType フォント機能をサポートします。以下は、これらの機能によって、文字品質が大幅に向上する例です。以下の行を XamlPad に入力し、テキストがどのようにレンダリングされるかをテストしてください (ここで使用している活字は、最新バージョンの Windows Vista でのみ利用可能なので、このテストには Windows Vista を使用する必要があります)。

<RichTextBox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" FontFamily="Segoe Script" FontSize="44" />

wpf101_16.gif

"o" や "t" のような個々のグリフが、完全にその文脈に応じて変化することに注意してください。この変化は、フォント内に設定された追加のヒント情報が、レンダリング エンジンに対し、隣接する文字に応じてどのグリフを使用するかを指定することによって生じます。特にスクリプト フォントでは、はるかに自然な "手書き" のような味わいのある文字が表示されます。

さらに劇的な例として、以下の美しい筆記体の文字をご覧ください。Windows Presentation Foundation が Adobe Compact Font Format (CFF) をサポートしているおかげで、このような文字が可能になりました。これは、Bickham Script Pro です。

wpf101_17.gif

この例では、コンテキストに応じて、グリフの変化 (r、y、l、g) や結合 (Th) がどのように行われているかに注目してください。このような洗練された機能が、Windows Presentation Foundation では標準で提供されます。

Windows Presentation Foundation では、TextBlock または TextFlow を使用してテキスト ランを表示できます。TextBlock が単純に単一ブロックのテキストを表示するのに対し、TextFlow は、XAML で使用し、複数のパラグラフで構成されるコンテンツを表示するのに便利です。ビジュアル レイヤでは、DrawingContext.DrawText() が、GDI の世界での DrawText に相当し、TextRun や Glyph など、概念を表現するクラスが存在します。FormattedText は、テキスト API 内で特に便利なクラスです。テキストを入力し、BuildGeometry() メソッドを使用してベクトル図形を抽出すれば、通常のベクトルを使用できる場所であればどこででもそのベクトル図形を使用できます。

Windows Presentation Foundation には、個別のテキスト ランのレンダリングをサポートするだけでなく、読みやすくするための強力な制御機能が含まれています。たとえば SinglePageViewer クラスは、フロー ドキュメントのコンテナを提供し、そのコンテナが多彩なコンテンツをホストすることができます。このモデルは、大量のテキスト コンテンツの表示が必要となる電子ブックなどに適しています。

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 ColumnWidth="250" ColumnGap="20" ColumnRuleWidth="1" ColumnRuleBrush="Gray"
              Background="AliceBlue" FontFamily="Palatino Linotype" FontSize="14"
              Typography.DiscretionaryLigatures="True" Typography.NumeralStyle="OldStyle">
<Paragraph>In many of the "black and white" TrueType fonts that were included with Windows 3.1 (e.g. Times New Roman and Arial) hints were added to many glyphs to change the natural advance width to something that allowed for better symmetry of the characters.  Often widths were changed by ±2 pixels. With the low resolution of black and white pixels, things like symmetry are much more important for reading than accuracy of the character width (WYSIWYG). Because of the extra resolution available along the "widths" axis, ClearType allows us to get both the symmetry for the glyphs and more accurate advance widths. Even with this extra accuracy, GDI is still limited to expressing glyph widths in integer pixels, so ultimately all widths round to the nearest pixel.</Paragraph>
<Paragraph>Because we wanted to enable ClearType for all fonts on the system in GDI, we needed the widths with ClearType on to be the same as with ClearType off (this is what we had previously done with font smoothing.) In order to get this behavior, we had to add a mode to GDI called compatible widths, which forces the advanced with to be the same as "black and white". In order to do this we have to insert a little error into the glyphs. Unfortunately, this error noticeably distorts the glyph shape and at smaller glyph sizes makes incorrect gamma settings more problematic (the tuner can help here.)</Paragraph>
<Paragraph><Floater Background="LightYellow" Padding="10" BorderThickness=".5" BorderBrush="Gray" Width="140">
    <Paragraph FontFamily="Calibri" FontWeight="Bold" FontSize="18">GDI Widths</Paragraph>
        <List>
      <ListItem><Paragraph>Compatible</Paragraph></ListItem>
      <ListItem><Paragraph>Natural</Paragraph></ListItem>
    </List>
</Floater>This means that for GDI there are two width options available. Firstly, compatible widths, which by adding some error, creates widths exactly the same as black and white and font smoothing. Non-compatible widths is called "natural widths" and this mode became available in Windows XP SP1. It provides high quality ClearType, but since it is in GDI, it is still limited to integer pixels.</Paragraph>
<Paragraph>Windows Presentation Foundation uses sub-pixel positioned ClearType, which allows the full precision of ClearType to be displayed on the screen. Using this option, glyphs can both start and end on arbitrary pixel positions. This, especially when combined with kerning, allows us to have very high quality word shapes on the display. High quality spacing is an important part of making good looking text on the screen. Sub-pixel positioning gives us a very slight loss of contrast, but this is made up by the excellent spacing. This high precision spacing allows us to position text in a device independent manner.</Paragraph>
</FlowDocument>

wpf101_18.gif

必要なエクスペリエンスに合わせて、SinglePageViewer コントロールのスタイルを再設定できます (ボタンの変更など)。

注釈

注釈は、DocumentViewerBase に基づく 2 つのドキュメント コントロールに組み込まれています。これらのコントロールは、フロー コンテンツへのアンカリングをサポートする SinglePageDocument と固定コンテンツへのアンカリングをサポートする DocumentViewer です。開発では、注釈の追加と削除を数行のコードでサポートできます。既定では、公開されたスキーマを使用して XML ストリームに保存されます。開発者が追加のコードを作成して、カスタム ストアを実装することもできます。たとえば、分離したストアに注釈を保存したり、注釈を共有するために Web サービスを使用してリモート サーバーに保存することができます。

Windows Presentation Foundation では、強調表示とメモの 2 つの注釈がサポートされています。強調表示は、紙に蛍光ペンで印を付ける作業と似ており、コンテンツの一定の範囲を選択して別の色を設定します。一方、メモは、コンテンツにインクやテキスト コンテンツを追加することにより、コメントの追加などを行えます。メモには、他のコントロールと同様、スタイルを設定できます。たとえば、ユーザーが注釈を設定するときに、メモの背景色を変えることができます。

スタイルとデータ バインディング

アプリケーションのスタイルは、リソース、スタイル、テンプレート、トリガ、ストーリーボードを統合する広い概念の用語です。スタイルは、アプリケーションの要素について、外観と対話形式の動作を一元的に定義します。

Windows Presentation Foundation は、アプリケーションの外観と操作感を決定する強力な機能を備えており、Windows Forms のような、基本的なカスタマイズとオーナー描画モデルとの間に大きな差異があるテクノロジに比べて、容易に複雑性を排除できます。ただし、あらゆるテクノロジを使用できるので、開発者がいろいろと試した結果、統一性がなく使いにくいアプリケーションになる危険性はあります。優れたアプリケーション設計とは、作成するアプリケーションと対象のユーザーに適した設計であり、美的センスと高いユーザビリティ、何百回使用しても初めてのときと同じように楽しんで使用できる飽きの来ない設計のことです。

スタイル

スタイルによって、あらゆるコンテンツの外観と操作感が決まります。スタイルには名前を付けて、その名前によって使用できるものもあれば、特定のコントロール タイプで使用されるものや (Button)、その両方の性質を持つものもあります。スタイルは、別のスタイルを基に作成することもできます。以下に、ボタン スタイルを作成する簡単な例を示します。

<StackPanel xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Margin="15" >
   <StackPanel.Resources>
      <Style x:Key="MyStyle" TargetType="{x:Type TextBox}">
         <Setter Property="Background" Value="Green" />
         <Setter Property="Foreground" Value="White" />
      </Style>
   </StackPanel.Resources>
   <TextBox Style="{StaticResource MyStyle}">TextBox 1</TextBox>
   <TextBox Style="{StaticResource MyStyle}">TextBox 2</TextBox>
   <TextBox>Unstyled</TextBox>
</StackPanel>

wpf101_19.gif

このコードでは、TextBox コントロールを対象とする単一の名前付きスタイルが入ったリソース ディクショナリを宣言しています。スタイル内には、前景と背景の 2 つのプロパティを設定しています。これを利用するには、テキストボックスを設定して、リソース ディクショナリにあるスタイルを使用するだけです。3 つ目のテキストボックスは、名前付きスタイルを参照していないので、既定のスタイルを受け取ることに注意してください。

テンプレート

テンプレートは、コントロールまたはデータ型のビジュアル構造を記述することによってスタイルを拡張します。これによって、Windows Presentation Foundation が持つさまざまな表示機能が実現されます。テンプレートでは、合成を使用してオブジェクトのビジュアル ツリーを記述できます。以下の例では、既定のボタン スタイルをスタイル付きの楕円に変更しています。

<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <StackPanel.Resources>
      <Style x:Key="MyStyle" TargetType="{x:Type Button}">
         <Setter Property="Background" Value="SkyBlue" />
         <Setter Property="Foreground" Value="White" />
         <Setter Property="Cursor" Value="Hand" />
         <Setter Property="Template">
            <Setter.Value>
               <ControlTemplate TargetType="{x:Type Button}">
                  <Grid>
                     <Ellipse Name="rect"
                        Fill="{TemplateBinding Property=Background}" />
                     <ContentPresenter Margin="20,0,20,0"
Name="content" TextElement.Foreground="{TemplateBinding Property=Foreground}"
TextElement.FontSize="{TemplateBinding Property=FontSize}"
                                             VerticalAlignment="{TemplateBinding Property=VerticalContentAlignment}"
   HorizontalAlignment="{TemplateBinding Property=HorizontalContentAlignment}" />
                  </Grid>
                  <ControlTemplate.Triggers>
                     <Trigger Property="IsMouseOver" Value="true">
                        <Setter TargetName="rect"
Property="Fill" Value="LightBlue" />
                        <Setter TargetName="content"
Property="TextElement.Foreground" Value="Black" />
                     </Trigger>
                  </ControlTemplate.Triggers>
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
   </StackPanel.Resources>
   <Button Height="200" Width="400" FontSize="24pt" Style="{StaticResource
MyStyle}">Click here</Button>
</StackPanel>

wpf101_20.gif

この例では、ContentTemplate の中の ContentPresenter に、オブジェクトの実際のコンテンツが入っていることがわかります。また、楕円内のプロパティの一部をその親テンプレートにバインディングすることで、開発者がそれらの値をボタンに設定すると、その基になる適切な要素が変更されるようになっています。

トリガとストーリーボード

トリガとスタイル、テンプレートを併用すると、ユーザーとアプリケーションの間で、多彩で動的な対話が可能になります。トリガは、指定した条件が true になったときに起動されます (上の例では、ボタンの上にマウス ポインタ合わせるとトリガが起動します)。次の例では、要素にフォーカスが移ると背景色が変化します。

<Trigger Property="IsFocused" Value="true">
 <Setter Property="Background" Value="Purple" />
 </Trigger>

セッター プロパティ内で TargetName="ContentBorder" を使用して、オブジェクトの特定のサブ要素 (たとえば、ListBox 内の要素) を対象とすることができます。

イベント トリガを使用すると、アニメーションを実行するためのストーリーボードをサポートできます。To と From の両方のプロパティを設定しない場合、このイベントが別の設定イベントをオーバーライドしても、問題なく動作します。

<EventTrigger RoutedEvent="Mouse.MouseEnter">
   <EventTrigger.Actions>
      <BeginStoryboard>
         <Storyboard TargetProperty="MaxWidth">
            <DoubleAnimation Duration="0:0:1" To="150" />
         </Storyboard>
      </BeginStoryboard>
   </EventTrigger.Actions>
</EventTrigger>

データ バインディング

アプリケーションはどれでも、何らかのフォームを使用します。Windows Presentation Foundation は、データをアプリケーションにバインドしたり、アプリケーションからデータを操作できるよう、豊富なデータ サービスのセットを提供しています。

ほとんどのシステムでは、ユーザー インターフェイスとデータが、論理構造の点でも、作成する開発者から見た場合でも分離されています。データ バインディングは、これら 2 つのエンティティを結び付けます。しかし現在、多くのプラットフォームで行われているデータ バインディングには、機能がブラックボックス化している、複数のデータ モデル (XML、リレーショナル、オブジェクト) を完全にサポートしない、拡張が困難などの問題があります。その結果、多くの開発者がプラットフォームによるデータ サポートを無視して、独自のデータ メカニズムを作成しています。

Windows Presentation Foundation のデータ バインディング モデルは、これらの問題への対応を試みています。Windows Presentation Foundation では、最初からデータが最も重要な構成要素であり、プロパティ エンジンでデータをサポートするだけでなく、XAML から宣言によってデータをサポートします。Windows Presentation Foundation では、1 回限り (サーバーの更新を無視)、一方向 (読み取り専用)、双方向 (読み書き可能) の 3 種類のデータ バインディングをサポートしています。

基本的なデータ バインディング

まず必要なのは、データ プロバイダを作成することです。データ プロバイダは、XML、リレーショナル、オブジェクトの各データ ソースに接続するために使用します。DataSourceProvider 抽象クラスから派生して、独自のプロバイダを作成することもできます。

以下の例では、インライン XML データを使用してプロバイダを作成しています。

<XmlDataProvider x:Key="nodePrototype" XPath="AuctionItem">
<AuctionItem Description="AuctionItem" StartPrice="3.50">
</XmlDataProvider>

次は、単純にそれにバインドします。

<TextBox>
   <TextBox.Text>
      <Binding XPath="@Description" Source="{StaticResource nodePrototype}" />
   </TextBox.Text>
</TextBox>

親コンテナに複数のバインディングが格納されている場合、DataContext をソースに設定しておけば、バインディングのたびにソースを設定する必要がなくなります。最後に、マークアップ拡張ショートカットを使用して、オブジェクト自体の中に「Value="{Binding XPath=@StartPrice}"」と記述します。

コンテンツの一覧表示の利用

多くの場合、個別の項目にバインドするだけでは不十分です。一般的には、オブジェクトのコレクションにバインドして、それらをまとめて表示する方法が利用されています。Windows Presentation Foundation では、この情報を表示するための独自のビューを生成できる ItemsControl が用意されています。たとえば、以下のようなデータ ソースが存在するとします。

<AuctionItems>
   <Item Title="Slightly unwashed, tatty teddy bear" />
   <Item Title="Threadbare pair of socks" />
   <Item Title="A used tea towel" />
   <Item Title="Packet of cereal, mostly uneaten" />
   <Item Title="A dead stick insect" />
</AuctionItems>

以下のコードを使用して、これをバインドします。

<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <StackPanel.Resources>
      <XmlDataProvider x:Key="myItems" Source="c:\mydata.xml" XPath="/AuctionItems" />
   </StackPanel.Resources>
<Border>
   <ItemsControl ItemsSource="{Binding Source={StaticResource myItems}, XPath=/AuctionItems/Item}"
      DisplayMemberPath="@Title" >
   </ItemsControl>
</Border>
</StackPanel>

ItemsControl が基になるデータの変更を取得し、ビューを直接更新します。各項目についてこれが繰り返され、各項目に対して ContentControl が生成されます。ContentControl を使用して、個々のデータを自由に表示できます。この例では、既定の表示方法を使用して、ラベルとともに @Title XPath クエリにバインドされた値を表示します。

データのプレゼンテーション

Windows Presentation Foundation では、開発者が、バインディング自体からデータを抽出するときに、そのデータの表示方法を選択できます。データ項目の表示方法は、データ テンプレートによって制御します。データ テンプレートでは、データ型を定義すると、このデータのすべてのインスタンスが指定した方法で表示されます。

この例では、Windows Presentation Foundation を使用して、XAML による RSS ブラウザを作成します。

<DockPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Margin="10">
   <DockPanel.Resources>
      <XmlDataProvider x:Key="Blog" Source="http://blogs.msdn.com/tims/rss.aspx" />
      <DataTemplate x:Key="TitleTemplate">
         <TextBlock Text="{Binding XPath=title}"/>
      </DataTemplate>
   </DockPanel.Resources>
   <Label Content="{Binding Source={StaticResource Blog}, XPath=/rss/channel/title}"
FontSize="24" FontWeight="Bold" DockPanel.Dock="Top" />
   <Label Content="{Binding Source={StaticResource Blog}, XPath=/rss/channel/description}" FontSize="18" DockPanel.Dock="Top" />
   <DockPanel DataContext="{Binding Source={StaticResource Blog}, XPath=/rss/channel/item}" >
      <ListBox DockPanel.Dock="Left" ItemsSource="{Binding}" ItemTemplate="{StaticResource TitleTemplate}" IsSynchronizedWithCurrentItem="True" />
      <Frame Source="{Binding XPath=link}" Width="Auto" />
   </DockPanel>
</DockPanel>

wpf101_21.gif

ここで、データ テンプレートを使用して、リストボックス内の項目の表示方法を定義します。この例では、TextBlock を使用してデータにバインドされた項目を表示しますが、グラフィクスやメディア、ハイパーリンク、その他のコンテンツ タイプを表示するように簡単に拡張できます。個々の投稿の詳細を表示するために、IE のホストとして Frame コントロールを使用します。

もちろん、すべての機能を持つ RSS ブラウザの構築には、さらに多くの作業が必要です。項目のキャッシュ、未読/既読ステータス、複数のフィード、見やすいスタイル、その他多くの要素が必要になります。しかし、データ バインディングのみを使用して、ここに表示された基本的なフィード リーダーを作成できたことだけでも、XAML の能力を十分に証明しています。

データのプレゼンテーションの整理

データのフィルタリング、グループ化、並べ替えは、開発者が求める機能です。Windows Presentation Foundation では、これらの機能が CollectionView オブジェクトによってサポートされています。これにより、同じコレクションを同時に異なるビューで表示できます。この機能は、IEnumerable をサポートしているデータ フォームなら、どれに対しても利用できます。また ICollectionView を実装すれば、独自の並べ替え、フィルタリング、グループ化のアルゴリズムを使用できます。

リソース セクションに、以下のいずれかを追加します。

<CollectionViewSource x:Key="SortByName" Source={StaticResource Blog}"
<CollectionViewSource.Sort>
<scm:SortDescription PropertyName="@title" Direction="Ascending" />
</CollectionViewSource.Sort>
</CollectionViewSource>
<CollectionViewSource x:Key="GroupByDate" Source={StaticResource Blog}"
<CollectionViewSource.GroupBy>
<scm:PropertyGroupDescription PropertyName="@pubdate" StringComparison="OrdinalIgnoreCase" />
</CollectionViewSource.GroupBy>
</CollectionViewSource>

並べ替えを使用するには、新しいキー名にバインドするだけです。基になるデータ ソースにバインドする必要はありません。

グループ化するには、グループ ヘッダーの表示に使用するグループ スタイルを次のように指定する必要があります。

<ItemsControl ItemsContainerStyle="" ItemsSource="{Binding Source={StaticResource myItems}">
   <ItemsControl.GroupStyle>
      <GroupStyle HeaderTemplate="{StaticResource groupingHeaderTemplate}" />
   </ItemsControl.GroupStyle>
</ItemsControl>

データのプレゼンテーションのカスタマイズ

データをリストとして表示しない場合は、どうすればいいでしょうか。たとえば、情報をグラフに表示する場合などが考えられます。Windows Presentation Foundation では、そのような表示も可能です。Windows Presentation Foundation のデータ バインディング サポートでは、すべてのコンテンツ コントロールが対象となります。たとえば、Button、Window、ToolTip、Label は、すべて ContentControls です。ListBox、ComboBox、TabControl は、すべて ItemsControl から派生します。

ドキュメント サービ

Windows Presentation Foundation 自体だけでなく、Windows Vista プレゼンテーション テクノロジには、ドキュメントと印刷ライフサイクルを処理する 2 つの新しい仕様が含まれています。

  • Open Packaging Conventions は、一連のファイル形式のパッケージング仕様、および任意のアプリケーションで使用できる関連のサービスを定めています。Open Packaging Conventions の仕様は ZIP ファイルに基づいており、それに従ってパーツ/リレーションシップの抽出と ZIP ファイルにアクセスするためのサービスが実現されます。

  • XML Paper Specification は、Open Packaging Conventions の仕様に基づく固定のページ付きドキュメントについて、マークアップとレンダリングのルールを定めています。XML Paper Specification の中には、XPS Document という特定の固定形式の実装も含まれています。

Open Packaging Conventions

Open Packaging Conventions を使用する場合は、次の 3 つの主なシナリオが想定されます。

  • カスタム ファイル形式の構築

  • XPS ドキュメントと Office 12 コンテンツへの直接アクセス

  • XPS ドキュメント、Office 12、またはカスタム ファイルのドキュメント解像度の指定

Open Packaging Conventions は、ユーザー独自のファイル形式に対して使用できます。その場合、用意されている共通サービスを利用できます。

パッケージング モデルは、ファイル形式の基盤を提供します。これは、Open Packaging Convention Specification (現在、v0.75) に定められています。パッケージはすべてのアプリケーションで利用可能です。また複数の実装が現在開発中です。中でも Office 12 が、その新しい .docx、.xlsx、.pptx 形式にこの仕様を使用します。このファイルの内容にアクセスするには、パッケージング サービス (パーツとリレーションシップ) を使用するか、標準の ZIP ユーティリティを使用します。

ファイル rels.relx は、一連のファイルのマスター インデックスで、メタデータ プロパティ、ドキュメント本体、サムネイルなどが入っている他の XML ファイルへのリンクが含まれています。

Open Packaging Convention API は、System.IO.Packaging ネームスペース (WindowsBase アセンブリ内) にあります。ここでは、Package、PackagePart、PackagePartCollection などのクラスにアクセスできます。API は、次に示すように、パッケージのオープンとクローズ、パーツとリレーションシップの作成と削除、パーツの名前やコンテンツタイプおよびストリームの取得、パーツ ストリームの読み書き、およびリレーションシップの ID やタイプおよび URI の取得が可能です。

const string relType = "http://schemas.microsoft.com/xps/2005/06/fixedrepresentation";
Package p = Package.Open("c:\\package.container", FileMode.Open);
PackageRelationshipCollection packRels = p.GetRelationshipsByType(relType);
foreach (PackageRelationship pr in packRels)
{
   Console.WriteLine(pr.RelationshipType);
   PackagePart part = p.GetPart(
      PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), pr.TargetUri));
   Console.WriteLine(part.ContentType + part.CompressionOption);
   // do something with part.GetStream() here.
}

パッケージングされたコンテンツのヘッダーには、3 つの主なサービスが利用できます。これらを使用して、ドキュメントの認証とコンテンツという共通の概念を共有できます。3 つの主なサービスは以下のとおりです。

  • 重要なプロパティの共通メタデータ : 以下のようなプロパティの共通セットがあります。

    • カテゴリ

    • コンテンツのステータス

    • コンテンツ タイプ

    • 作成者

    • 作成日

    • 最終変更日

    • 説明

    • キーワード

    • 最終変更者

    • タイトル

  • デジタル署名は、署名したコンテンツが改ざんされていないことを検証するための方法です。不正があった場合は、エンドユーザーはコンテンツを拒否できます。これは、すべての Open Packaging Convention 形式で利用可能です。証明書は、XML デジタル署名と互換性があり、X.509 標準に従います。署名対象のパーツは、署名ポリシーによって決定されます。たとえば、XPS Document Viewer ポリシーでは、定義されたすべてのパーツとリレーションシップに署名されます。証明書は、そのパーツ内に保存することも、証明書の権利内に含まれる署名パーツに埋め込むこともできます。ドキュメントは、PackageDigitalSignatureManager クラスを使用して署名します。PackageDigitalSignatureManager クラスは、署名自体を表し、署名の検証にも使用できます。

  • 権利管理Open Packaging Conventions では、特定の権利管理ソリューションの使用は必須ではありません。ただし、既定のソリューションが用意されています。このソリューションは、Windows Vista を対象にしたすべてのコードで使用できます。この既定のソリューションは、Windows Rights Management Services と呼ばれます。この API は、System.Security.RightsManagement ネームスペースにあり、これを使用してパッケージを実装するデータ ファイルに対し、権利管理コントロールを適用できます。

XML Paper Specification

XPS Document 形式は、カスタム ファイル形式の一例として捉えることができます。XPS ドキュメントには、以下のようなパーツが含まれています。

  • FixedDocumentSequence (ルート)

  • FixedDocument (ドキュメント マークアップ)

  • FixedDocument (ページ マークアップ)

  • Font (埋め込みフォント)

  • Image (埋め込みイメージ)

  • Thumbnail (ページ サムネイル イメージ)

  • PrintTicket (プリンタ設定)

XPS Document 内に、ドキュメント ソリューションのパッケージ API に置き換わる特定の API があります。これらは、XpsDocument、IDocumentSequenceReader、IFixedDocumentReader などです。これらの API を使用すると、ドキュメントの操作、パーツの追加と削除、重要なプロパティの取得と設定を行うことができます。これらの API は基本パーツ API よりも使いやすくなっています。

XPS Documents は、マークアップの互換性を利用して拡張が可能です。これは、XAML のマークアップの互換性と同じく、Ignorable、ProcessContent、AlternateContent、および MustUnderstand を設定できます。

アプリケーション モデル

Windows Presentation Foundation は、アプリケーション内のロジック フローを管理するためのプリミティブを提供します。既存のアプリケーション フレームワークは、その多くが何らかの形で制約されています。たとえば、MFC は、アプリケーションが MFC の構造に適している限り、アプリケーション構築に優れたフレームワークです。しかし、その限界を超えてしまうと、MFC 自体が障害になることも少なくありません。場合によっては、一般的なユーザー エクスペリエンス モデルのためのインフラストラクチャが欠落していることもあります (たとえば、Web ブラウザによって入力されるナビゲーション モデル)。アプリケーションレベルの優れた管理機能を持つプラットフォームはあまり存在しません (たとえば、Win 32 では、他のウィンドウへのメッセージのポストが必要になることが少なくありません。Web モデルでは、問題を改善する AJAX などのテクノロジが使用されていないために、ポストバック遅延が大きな問題となっています)。

ほとんどのアプリケーションは、以下のサービスを必要とします。

  • アプリケーション全体のステート情報 (アプリケーションの有効期間全体にわたる変数の追跡)

  • OS との対話 (アプリケーションのシャットダウンなど)

  • ウィンドウとリソースの管理

  • ファイルとユーザー データの保存

  • ユーザー インターフェイス モデル

  • ホストと配布

これらは、Windows Presentation Foundation アプリケーション モデルが重視する領域を表しています。

一般的なアプリケーション サービス

Windows Presentation Foundation は、データ管理、システム インタラクション、および UI モデルのための一連のオプトイン サービスを提供しています。インフラストラクチャは利用可能ですが、操作を妨げることはありません。また、ほとんどのアプリケーションが必要とする共通サービス (たとえば、リソース サービス) も用意されており、Windows Presentation Foundation で抽象化することができます。最も重要なことは、基本アプリケーションの作成を単純化する必要があるということです (アプリケーション フレームワークができるまで、標準の Windows の "hello world" アプリケーションを作成するのに、数百行のコードが必要だったことを覚えている方はいらっしゃるでしょうか)。

すべてのアプリケーションの基本クラスは、<Application> 要素です。これによって、アプリケーションのライフタイム (OnStartup, OnExit) とリソース管理が抽象化され、セッション データ (ASP.NET が提供するセッション データに近いデータ) を保存するためのプロパティ バッグが提供されます。また Application のサブクラスを作成して、機能を拡張することもできます。Application クラスは、Win32 の多くの WM_ メッセージを管理対象となるイベントに対して抽象化します (たとえば、アプリケーションのアクティブ化または非アクティブ化)。

アプリケーションのリソースは、アセンブリ内に埋め込む、アプリケーション ディレクトリにファイルとしてローカルに保存する、アプリケーションの実行元のサーバー上に保存する、別のアセンブリ内に埋め込む、という 4 とおりの方法で保存できます。リソースにアクセスするには、以下のようなコードを使用します。

アセンブリに埋め込まれている場合

<Image Source="Mushroom.jpg" />

アプリケーション ディレクトリにローカルに保存されている場合

<Image Source="Mushroom.jpg" />

アプリケーションのサーバーに保存されている場合

<Image Source="pack://siteoforigin:,,,/Images/Quiche.jpg" />

他のアセンブリ内に埋め込まれている場合

<Image Source="Food;Component/Egg.jpg" />

(上の 3 番目の方法で、siteoforigin は、サーバー名のプレースホルダではなく、固定のキーワードを表します)

もう 1 つの便利なサービスは、アプリケーション ストレージです。従来、アプリケーションのデータは、ファイル システムに保存される場合が多く、そのオプションが Windows Presentation Foundation にも残っています。アプリケーションは、隔離されたストレージ領域にデータを保存することもできます。この場合、クォータベースのモデルが提供され、部分信頼のシナリオでサポートされます。これには、IsolatedDataFileStream オブジェクトを使用します。あるいは、.config ファイルかレジストリ (設定用)、場合によってはクッキー (Web ベース アプリケーション用) を使用することもできます。

Windows Presentation Foundation が提供する 3 番目のサービスでは、シングル ドキュメント インターフェイス (SDI) とナビゲーションベースのインターフェイスの両方を含む複数の ユーザー エクスペリエンス モデルをサポートします。ダイアログ ベースの SDI モデルでは、ウィンドウやダイアログ、コントロールが使用され、機能はメニューによってユーザーに提示されます。ナビゲーションベースのアプリケーションは、Page、Hyperlink、NavigationWindow などの Windows Presentation Foundation クラスを使用して、Web メタファーに密接に合致するモデルを提供します。Windows Presentation Foundation では、アプリケーションが 1 つのモデルだけを使用するように強制されることはありません。アプリケーションでモデルを 1 つだけ使用することは、Windows ベースを基盤としており、ウィザードやその他の "手順を示す" タスクにページベースのモデルを使用するアプリケーションでは、一般的なことです。実は、Windows Presentation Framework は、MDI (マルチ ドキュメント インターフェイス) をネイティブにサポートしていません。設計者にはタブ モデルか (Visual Studio による)、マルチ ウィンドウ モデル (Microsoft Word による) の使用を推奨します。

ナビゲーション ウィンドウに関して言うと、アプリケーション モデル内での 1 つの課題は、Web のハイパーリンクが実際には BASIC の "GOTO" 文をモデルにしており、その中に組み込まれたページを起動するという発想がないということです。Windows Presentation Foundation では、この問題に対する解決方法として、"GOSUB" 文に非常に近い PageFunction が用意されています。XAML から Page オブジェクトの代わりに PageFunction オブジェクトを使用すれば、呼び出し元のコードからこのページ機能のインスタンスを作成したり、戻りイベントのイベント ハンドラを作成してそれにナビゲートできます。ユーザーが呼び出し先のページを使用し終わったら、単に OnReturn イベントを呼び出し、返すパラメータを渡します。

Web ベースのアプリケーション

Windows Presentation Foundation の対象は、Windows ベースのアプリケーションだけではなく、ブラウザ ベースのアプリケーションもサポートします。Web ブラウザ アプリケーション (XBAP) は、セキュリティ サンドボックスの中で実行されています。特権が設定されたサービスを呼び出すことができないので、セキュリティやインストール プロンプトは不要です。また、従来の意味でのインストールは行われないので、[スタート] メニューに表示されることも、Program Files ディレクトリにファイルが作成されることもありません。このアプリケーションは ClickOnce (.NET Framework 2.0 の一機能) によって展開されます。XBAP はオンラインのみのアプリケーションなので、"断続的に接続される" シナリオには適していません。

ブラウザによってホストされるアプリケーションとスタンドアロンのアプリケーションの両方に対応できる、単一のプラットフォームを使用することの利点の 1 つは、両方のプログラミング モデルが同じであるという点です。たとえば Outlook では、豊富な機能を持つクライアント アプリケーションと Web アプリケーション (Outlook Web Access) 用に完全に別個のコード ベースが存在しますが、それと比較して、このモデルは Web とシン クライアント アプローチをサポートするアプリケーションにとって、明らかに利点があります。

XBAP はどのように作成するのでしょうか。それには、Visual Studio 2005 に付属のテンプレートを使用するか、単純に以下の 3 つのプロパティをプロジェクト ファイルに設定します。

<HostInBrowser>True</HostInBrowser>
 <Install>False</Install> 
<TargetZone>Internet</TargetZone>

既存のアプリケーションを変換する場合は、条件式によるチェック (#if (XBAP)...#else...#endif) か、アクセス許可レベルの実行時チェックを使用して、サンドボックスに適さないコードを削除する必要もあります。

ハイパフォーマンスなアプリケーションの作成

Windows Presentation Foundation は、豊富な機能を搭載したアプリケーションを作成するための強力な機能を備えていますが、同時に、対象のコンピュータの特性の違いを考慮してアプリケーションを設計しなければ、パフォーマンス上の問題が生じる可能性があります。

Windows Presentation Foundation は、ハードウェア レンダリングを適切に利用します。Direct3D を使用して、DirectX 7 以上で高速化されたレンダリングを行い、DirectX 9 または Pixel Shader 2.0 対応のグラフィック カードでは、それ以上の最適化が実現されます。このような機能を持たないコンピュータでは、CPU ベースの SSE および SSE2によって最適化されたラスタライザを使用して、ソフトウェア レンダリングが行われます。ソフトウェア レンダリングは、Windows Presentation Foundation でハードウェア パイプラインによるレンダリングができない場合にも使用され、コンピュータのハードウェア構成に関わらず、常にレンダリング出力が保証されます。

この結果、Windows Presentation Foundation にはハードウェアとソフトウェアの両方のパイプラインがあり、それぞれが異なるパフォーマンス特性を持つことになります。つまり 2 つのコード パスがあるので、パフォーマンスの予測が非常に困難になります。実際には、アプリケーションが同じであれば、ハードウェア レンダリングの方が高速なのは確実です。これは単に、最小要件の設定の問題です。Windows Presentation Foundation は、単純な実行時ハードウェア検出をサポートしており、リソース ディクショナリを使用して、アプリケーションをプラットフォームに合わせて調整できます。

これには、以下のコードを使用します。

// tier will be 0, 1 or 2 where 2 is full hardware and 0 is software
int wpfTier = System.Windows.Media.RenderCapability.Tier >> 16;
// in this example, simply switch between software and hardware rendering
if (wpfTier == 0)
Resources.MergedDictionaries.Add(softwareRenderingDictionary);
else
Resources.MergedDictionaries.Add(hardwareRenderingDictionary);

Tier の上位ビットには Tier 番号に加え、トラップ可能な TierChanged イベントが含まれています (たとえば、下位の電源管理モードへのフォールバック)。0x20000 はハイエンド ハードウェアのサポート、0x10000 は基本ハードウェア レンダリング、0x00000 はソフトウェア レンダリングです。Tier 2 開発マシンでは、コントロール パネルの Display Properties アプレットの [Troubleshooting] タブを使用して、下位層に切り替えられます。

Tier を見分けるのは簡単ですが、適切なコンテンツをオーサリングするのは困難です。静的 2D コンテンツと単純な 2D アニメーションには、Tier 0 マシンを使用します。Tier 1 マシンも複数のアニメーション、不透明度の設定、大きな塗りつぶし領域に使用できます。Tier 2 は複雑な 3D コンテンツや放射線状のグラデーションに最適です。

パフォーマンス上の問題のデバッグ

ソフトウェア レンダリングは、アプリケーションが Tier 2 ハードウェアで動作している場合でも、任意の操作に使用されることに注意してください。たとえば、TileMode=Tile と設定すると、要素がソフトウェア ラスタライザ経由でレンダリングされます。

Perforator は、SDK の新しいツールで、実行中の Windows Presentation Foundation アプリケーションに接続してパフォーマンスを測定します。また、Windows Presentation Foundation のレンダリングをリアルタイムに変更して、パフォーマンス上の問題を診断することもできます。Perforator を使用すると、実行中の Windows Presentation Foundation プロセスに接続して、ソフトウェア レンダリングにフォールバックしたすべての要素を特定の色で表示できます。  

もう 1 つのツールは、ETW です。tracelog、racerpt、mofcomp などのツールは、ETW イベントの記録と処理が可能です。ドキュメントには、サポートするイベントが表示されます。

また、従来のプロファイリングを実行して、アプリケーションのボトルネックを特定できます。Visual Studio 2005 に付属の Enterprise Profiler Tool には、サンプリング モードとインストルメンテーション モードがあります。

さらに、CLRProfiler (マイクロソフトの Web サイトで提供されている既存のツール) を使用して、管理対象のヒープ割り当ての問題とそれに伴うパフォーマンス コストを調査できます。

パフォーマンスについてのヒント

仮想化は、大量のデータ処理が必要なアプリケーションのパフォーマンスを高める適切な方法です。Windows Presentation Foundation では、VirtualizingStackPanel コントロールによって UI の仮想化が可能です。項目数が多い場合、これは StackPanel の 70 倍も高速です。StackPanel と同じ動作も可能です。すべてのオブジェクトを常にツリーに置いておく必要がないので、最適な効果を得ることができます。

XAML のリソースとコーデックのリソース ディクショナリを使用して、共通リソースを再使用できます。このことは、何度も再使用されるコントロールの場合、特に重要です。また、固定可能なオブジェクト (ブラシまたはペンなど) は、変更する必要がない場合には、一定の状態で使用できます。これにより、リソースのサイズが縮小され (変更されたイベント ハンドラを Windows Presentation Foundation で追跡する必要がなくなるため)、パフォーマンスが向上します。

相互運用性および移行

Windows Presentation Foundation を知っている開発者は、既存のアプリケーションに対する影響の可能性を懸念します。次のような疑問を持つと思われます。すべてをゼロから作成しなおす必要があるのか、それとももっと簡単な方法があるのか。プラグインやコントロールはどうするのか。それらも作成し直す必要があるのか。

Windows Presentation Foundation は、優れた相互運用性を備えています。Windows Presentation Foundation を既存のコードの中で使用することも、既存のコードを Windows Presentation Foundation の中で使用することもできます。ただし、豊富な機能を十分に活用するには、Windows Presentation Foundation のみで構成されるエクスペリエンスを使用することを推奨します。データ バインディングやアニメーション、すべての要素を対象としたレイアウト サービスなど、共存環境では実現できない利点を利用できるからです。

エアスペース

コンテンツの一部を別のコンテンツの上でレンダリングするのは、場合によっては非常に困難です。たとえば、アルファブレンドは、適切状態にならない場合が多くあります。エアスペースの概念は、"テクノロジによる 1 ピクセル" です。エアスペースは四角である必要はなく、HREGIONS がサポートされていますが、すべての目的に対応するレイヤード ウィンドウ (WS_EX_LAYERED) はサポートされていません。

ここでは、アプリケーションで Windows Presentation Foundation の利点を活用して、すべてを作成し直すことなく、機能を向上させるためのアイデアをご紹介します。第 1 の方法として、Windows Presentation Foundation を使用して、クロム (メニュー、ツールボックス、ウィザード、ヘルプ システム) の外観を一新できます。2 番目の方法としては、クロムは Win32 のままにして、アプリケーション キャンバスに Windows Presentation Foundation を使用できます。3 番目の方法として、アプリケーションが、HTML などの出力形式を生成する場合、XAML のサポートを追加し、開発/設計ワークスペースに統合する方法があります。既存のコントロールを Windows Presentation Foundation でラップすれば、より広範なユーザーが利用できるようになります。

/clr への移行

既存の Win32 C++ アプリケーションを Windows Presentation Foundation に移行するための、最初の手順は、コードを Visual C++ 2005 に移行し、シームレスなマネージ コードの統合機能を利用することです。Visual C++ に移行することによって、セキュリティ (/gs) や信頼性の点でも利点があります。この時点では、ISO 標準の準拠事項が厳格になり、互換性に影響する変更点がライブラリやヘッダーに生じた結果、おそらくコンパイル エラーが発生します。加えて、セキュリティの問題や 64 ビットに対応していないコードに関して、数多くのコンパイル警告が発生する可能性があります。この最初の手順は少し面倒ですが、適切な結果を得ることができます。

/clr を追加すると問題なくコンパイルできますが、/clr を使用する場所については注意が必要です。/clr は、それが必要なソース ファイルでのみ使用することをお勧めします。不要なファイルにまで追加すると、コンパイルに時間がかかり、必要以上の作業が生じます。たとえば、C のファイルは C++ としてコンパイルする必要があり、それによってソースの数多くの問題が明らかになることがあります。これとは別に、含まれているヘッダー ファイルのアセンブリ コードに関して問題が生じることも考えられます。また、DllMain にマネージ コードが存在することに伴う問題もあります。この詳細については、Visual C++ のマニュアルを参照してください。

/clr スイッチを指定して DLL のコンパイルを行ったときと同様に、デバッガ モードを mixed に設定してください。不正なデバッガが選択されていないことを確認する必要があります (Visual Studio は実行可能形式に基づいてチェックするため)。

Win32 アプリケーションへの Windows Presentation Foundation の埋め込み

これをうまく機能させるには、Windows Presentation Foundation アプリケーション ロジックを HWND の内側に置きます。HwndSource を作成すれば、Windows Presentation Foundation が、サイズの大きい HWND のように動作します。

HwndSource source = new Source.RootVisual(); 

最初に、コンパイル時に /clr スイッチを追加して、CLR のサポートを追加する必要があります。次に、WinMain を [System::STAThreadAttribute] でマークします。さらに、PresenationCore.dll、PresentationFramework.dll、System.dll、UIAutomationTypes.dll への参照を追加します。ここで、マネージ コードのネームスペースを追加します。

namespace ManagedCode
{
   using namespace System;
   using namespace System::Windows;
   using namespace System::Windows::Interop;
   using namespace System::Windows::Media;
}

ここでは、新しい HwndSource を作成する必要があります。これには、以下のコードを使用します。

HwndSource^ source= gcnew HwndSource(...);
UIElement^ page = gcnew AvClock::Clock();
source->RootVisual = page;
return (HWND) source->Handle.ToPointer();
課題

上で紹介した手順を実行する前に、次の課題について検討することをお勧めします。

  • Windows Presentation Foundation 対応のネイティブなアプリケーションを再作成する場合と比較して、初期コストが小さい代わりに、長期的なコストがかかります。Win32 と Windows Presentation Foundation の間の境界を超える場合は、常に相互運用性の問題 (たとえばエアスペース) に対処する必要があります。

  • 混合モードのアプリケーションでは部分信頼のコードを使用できないため、Web ブラウザ アプリケーションにレガシ コードを埋め込むことはできません。このモデルを使用する場合は、ネイティブの Windows Presentation Foundation アプリケーションとしてコードを作成してください。

  • XAML と C++ を同じアセンブリ内で使用することはできません。異なるアセンブリでこれらを使用し、Win32 C++ ホストから XAML をロードすることは可能です。

  • 場合によっては、WinFX がインストールされたマシンと Win32 だけがインストールされたマシンの両方が混在する環境で、アプリケーションを実行することがあります。最新のリリースに付属する以下のコードを使用して、WinFX をチェックできます。

if (Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\WAP" != null) 
// WinFX Runtime Components are installed

まとめ

Windows Presentation Foundation は、アプリケーション開発者や設計者にとって新しい強力なツールです。将来のリリースの Windows に対応する戦略的プレゼンテーション基盤として、グラフィック ハードウェアの性能を十分に活用し、スタンドアロン アプリケーションから、Web ブラウザベースのアプリケーションやドキュメントまで、あらゆるものをサポートします。豊富な機能を持つ、臨場感にあふれたアプリケーション ユーザー エクスペリエンスを求める開発者や、Web モデルの限界に突き当たっている開発者にとって、Windows Presentation Foundation の早期導入は、とりわけ大きな利益につながることでしょう。

参照先

オーサリング ツール

Windows Presentation Foundation のブログ

© 2012 Microsoft. All rights reserved. 使用条件 | 商標 | プライバシー
Page view tracker