印刷用ページ      送信     
クリックして評価とフィードバックをお寄せください
MSDN
MSDN ライブラリ
テクニカルドキュメント
Windows Vista
 Windows Presentation Foundation におけ...
Windows Presentation Foundation における 2D および 3D 動的アニメーションの作成

Karsten Januszewski

Microsoft Corporation

January 2005, Updated June 2006

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

概要 : ここでは、Windows Presentation Foundation が提供する 2D アニメーション インフラストラクチャを使用してアニメーション タスク マネージャを作成する方法を説明した後、3D の世界に移って、動的アニメーション 3D メッシュを作成する方法を説明します。

適用対象:

Vista/.NET Framework 3.0 Beta 2

AvalonTaskMgr.msi サンプル ファイルのダウンロード.

目次

はじめに
CPU パフォーマンス カウンタ データへのアクセスと線グラフの追加
アニメーションの追加
アニメーション化した棒グラフの追加
まとめ

データ ビジュアライゼーションの目的で、Windows Presentation Foundation (WPF) を使用する非常に興味深いシナリオが用意されています。 WPF のアニメーション機能を使用すると、情報を本能的、直感的に表現できる可能性が広がります。 ほとんどの Windows ユーザーが経験しているデータ ビジュアライゼーションの 1 つは、タスク マネージャによる CPU 使用率のグラフィカル表示でしょう。 データ ビジュアライゼーションを説明するための 1 つの方法として、WPF を使用してこのデータ ビジュアライゼーションを実装します。 実装を行う中で、WPF プラットフォームのいくつかの機能をご紹介します。 まず、WPF の描画ブラシを使用するとグラフの作成がどんなに簡単かをお見せします。 2 番目に、シンプルで洗練されたアニメーション プログラミング モデルについて説明します。 3 番目に、アプリケーションが取得するデータをその場で使用することによって制御される動的アニメーションの作成テクニックを説明します。 最後に、3D の世界に少しだけ入って、動的アニメーション 3D メッシュの作成方法を示します。 最終的なアプリケーションのスナップショットを次に示します。

avalon2d-3d_fig1.jpg

はじめに

アプリケーション作成では、まずレイアウトを設定します。 Window.ResizeModeNoResize に設定して、アプリケーションのサイズ変更を抑制してあり、StackPanelGrid などのその他の WPF レイアウト コントロールのサイズ変更機能はまったく必要ないので、Canvas を使用してコントロールを配置しました。 キャンバスには、TextBlock、TextBlock、およびグラフ用の 2 つのキャンバスのあわせて 4 つのコントロールのみが存在します。 各コントロールは、その Canvas.Left プロパティの設定によってキャンバス上に固定されています。

次のステップでは、座標軸となる縦線と横線を表示して、グラフを追加します。 WPF には、DrawingBrush コントロールを使用してグラフを作成する非常に便利な機能が用意されています。この機能を使用すると、領域いっぱいに描画することができます。 描画自体は、四角形、楕円形など、さまざまな WPF の図形を使用して構成できます。 DrawingBrush のもっとも重要なプロパティは Drawing プロパティで、これによりブラシが使用する図形が決まります。 この例では、グラフを形成する 2 種類の線の組み合わせの図形を使用します。

DrawingBrush のもう 1 つの重要な機能は、同じ図形を並べて表示できることです。 DrawingBrush は、列挙型を取る TileMode プロパティをサポートします。 TileModeTile に設定することによって、表面に同じ図形をいくつも並べることができます。 これにより、並べて表示する 1 つの図形を宣言できます。 DrawingBrushViewport の設定によって、各図形のサイズが決まります。 次に、この DrawingBrush のキャンバスの背景を設定すると、キャンバス全体に画像が並べて表示されます。 したがって、緑のグリッドを作成するために、次のように、ブラシに縦の線と横の線の 2 本の線を設定します。

<DrawingBrush x:Name="gridBackgroundBrush" 
        Viewport="0,0,10,10" 
        ViewportUnits="Absolute"
        TileMode="Tile">
  <DrawingBrush.Drawing>
        <DrawingGroup>
          <DrawingGroup.Children>
            <GeometryDrawing Geometry="M0,0 L1,0 1,0.1, 0,0.1Z" Brush="Green" />
            <GeometryDrawing Geometry="M0,0 L1,0 1,0.1, 0,0.1Z" Brush="Green" />
          <DrawingGroup.Children>
        <DrawingGroup>
  <DrawingBrush.Drawing>
</DrawingBrush>

次のステップでは、キャンバスの背景にこのブラシを適用します。 Background は、 Canvas のプロパティなので、XAML の Background プロパティの下に、次のように DrawingBrush を入れ子にできます。

<Canvas.Background>
    <DrawingBrush x:Name="gridBackgroundBrush">...</DrawingBrush>
  </Canvas.Background>

しかし、この背景を再使用することもあるので、描画ブラシをリソースとして作成してから、背景を必要とするキャンバスのスタイルを作成する方が効率的です。

<Window.Resources>
  <DrawingBrush x:Name="gridBackgroundBrush">...</DrawingBrush>
  <Style x:Name="myCanvasStyle">
    <Canvas Background="{gridBackgroundBrush}" />
  </Style>
</Window.Resources>

その後、"myCanvasStyle" というスタイルを使用して、背景属性を設定できます。

CPU パフォーマンス カウンタ データへのアクセスと線グラフの追加

グラフができたので、これにアニメーションを追加しましょう。 まず、表示するデータ (この例では CPU 使用率のデータ) を取得する必要があります。 .NET Framework には、System.Diagnostics.PerformanceCounter でこのようなデータにアクセスするための便利なクラスが用意されています。 このクラスを使用して、数百種類のパフォーマンス カウンタを取得することができますが、ここでは全体の CPU 使用率だけを取得します。

次に、パフォーマンス カウンタの呼び出しに使用するための、インクリメントを使ってイベントを発生させるタイマが必要です。 WPF には、このようなタイマとして、System.Timer ネームスペースに、UITimer があります。 アプリケーションが現在の CPU 使用率を取得するときは、いつでもパフォーマンス カウンタから NextValue() メソッドを呼び出せば、値が提供されます。 ここでは、0.5 秒ごとに、値を要求するようにタイマを設定します。 Tick イベントをタイマと連動させることにより、新しい CPU 使用率に基づいてアニメーションを更新できます。

Windows Vista でこの API を使用して診断情報を取得するには、高いアクセス許可が必要です。 そのような高いアクセス許可を取得する方法は、それほど多くはありません。 洗練されていない方法で無理やり取得するには、アプリケーションを右クリックして [Run As Administrator] をクリックします。 しかし、このちょっとした情報を知らないユーザーもいれば、アプリケーションが失敗する理由は、正しいアクセス許可が付与されていないからだということを知っているユーザーもいます。 高い特権を取得するもう少し洗練された方法として、高度なアクセス許可を要求するための標準の Windows Vista ダイアログを起動する方法があります。 これを行うために、アプリケーションの横にマニフェストを並べて追加しました。これにより、requestedExecutionLevelrequireAdministrator 値を指定することによって、高度なアクセス許可が要求されます。 ご参考までに、マニフェスト全体を以下に示します。

<?xml version="1.0" encoding="Shift_JIS" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0" 
      processorArchitecture="X86"
      name="WPF Performance Monitor"
      type="win32" />
  <description>WPF Performance Monitor</description>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

このアプリケーションでは、アプリケーションに 2 つの操作が発生します。 第 1 に、特別な特権が必要であることをユーザーに示す、特別なアイコンがアプリケーションに関連付けられます。 第 2 に、アプリケーションの起動時に、ユーザーにプロンプトが表示されます。 これら両方のスクリーンショットを以下に示します。

avalon2d-3d_fig2.gif

avalon2d-3d_fig3.gif

その他にも知っていたほうがよいことがあります。 第 1 に、先ほど使用した横に並べる方法ではなく、.exe 自体にこのマニフェスト情報を埋め込む方法もあります。 これについては、ドキュメントが近々公開される予定です。 第 2 に、このマニフェスト情報を追加しても、アプリケーションが Windows XP 上で動作できることに変わりありません。 最後に、マニフェストを追加しても、デバッグのエクスペリエンスが向上するわけではありません。 高度なアクセス許可を必要とするアプリケーションのデバッグを行うには、高度なアクセス許可を使用して Visual Studio 自体を実行します。これにより、アプリケーションを実行するためのプロセスが Visual Studio によって作成されるときに、そのプロセスが高度な特権を持つようになります。 このように、Windows Vista では、このプロジェクトをデバッグするために、高度なアクセス許可を使用して Visual Studio を実行する必要があります。

XAML 内のウィンドウの Loaded イベントと、コード内の関連するイベント ハンドラを連動させることによって、ウィンドウの Loaded イベント内で、これらのコントロールと X および Y int を初期化します。

public partial class Window1 : Window
{
private int x = 0;
private int y = 0;
private int cpuInt;
private System.Diagnostics.PerformanceCounter performanceCounter;
private System.Threading.UITimer uiTimer;
 
private void WindowLoaded(object sender, EventArgs e) 
{
 
  //パフォーマンス カウンタの起動
  performanceCounter = new System.Diagnostics.PerformanceCounter("Processor", "% Processor Time", "_Total");
  //uitimer の起動
  uiTimer = new System.Threading.UITimer();
  uiTimer.Interval = new TimeSpan(5000000);
  uiTimer.Tick += new EventHandler(uiTimer_Tick);
  uiTimer.Start();
 
}
 
void uiTimer_Tick(object sender, EventArgs e)
{
  cpuInt = Convert.ToInt32(performanceCounter.NextValue());
  Do2DAnimation();
  CpuText.TextContent = cpuInt.ToString();
  y = cpuInt;
  x = x + 1;
}
}

ここで、Do2DAnimation メソッド内にコードを実装する必要があります。 線グラフを作成するためには、以前の使用率の値 (たとえば、80%) を確保し、そこから新しい値 (たとえば、20%) に線を引く必要があります。 この例では、CPU 使用率の値が Y 軸で表現され、各ピクセルが使用率を表しています。 時刻は X 軸で表現され、X 軸上の 10 ピクセルが 0.5 秒を表します。

ここで、Y 軸 0 がページの一番上にありますが、通常は 0 が一番下に、100 が一番上にあるので、そのように表示することにします。 そのためには、CPU の値を 100 から引いて、値を導く必要があります。 これで、Line 形の上に X1、X2、Y1、および Y2 を設定すると、次のような線分ができます。

private void Do2DAnimation()
{
 
 
  //X2、Y2 に相当する線を作成します。これは実際には点になります。
  Line segmentAnimation = new Line();
  segmentAnimation.X1 = new System.Windows.Length(x * 10);
  segmentAnimation.Y1 = new System.Windows.Length(100 - y);
  segmentAnimation.X2 = new System.Windows.Length((x * 10) + 10);
  segmentAnimation.Y2 = new System.Windows.Length(100 - cpuInt);
  segmentAnimation.Stroke = System.Windows.Media.Brushes.LimeGreen;
  segmentAnimation.StrokeThickness = new System.Windows.Length(1);
  CpuGraphAnimation2d.Children.Insert(0, segmentAnimation);
}

ブラシの Stroke プロパティで線の色を、StrokeThickness プロパティで太さを指定していることに注意してください。 最後に、キャンバスの子コレクションで、Insert メソッドを呼び出して、線をビジュアル ツリーに追加します。

上のコードを追加すれば、正しく機能するソリューションが得られ、チェックした点を通る線が挿入されます。 しかし、このコードは問題が生じる可能性があります。それは、このコードがキャンバスの最後を認識しないことです。 このコードを実行すると、WPF がキャンバスの幅を広げ、他のキャンバスを左側に移動させることによって、線の X 軸がキャンバスの境界の外に出ないように補正することがわかります。 WPF のこの動作はそれ自体は便利でしたが、別の問題が生じました。アプリケーションが実行されている限り、新しい線が次から次へと無限に作成されたのです。

このため、画面のサイズに合わせて決まった数の線を作成し、必要に応じてリサイクルする方が適切です。 そこで、X の値を記録し、キャンバスの端に達したときにそれをクリアすることが必要になります。 キャンバスは 200px なので、線を 20 個描くとキャンバスの端に到達します。 この方法を使用すると、先ほどの uiTimer_Tick メソッド内のコードを次のように更新できます。

void uiTimer_Tick(object sender, EventArgs e)
{
  cpuInt = Convert.ToInt32(performanceCounter.NextValue());
  Do2DAnimation();
  CpuText.TextContent = cpuInt.ToString();
  y = cpuInt;
  x = x + 1;
  if (x == 20)
  {
    CpuGraphAnimation2d.Children.RemoveRange(0, 20);
    x = 0;
  }
}

また、Loaded イベントを更新すると共に、グラフが再使用できる 20 個の線の配列を作成する必要があります。これによって、作成される線を Loaded イベントの線の配列に追加することで、線が無限に作成されるという先ほどの問題が解決されます。

for (int i = 0; i < 20; i++)
{
  Line line = new Line();
  line.Stroke = System.Windows.Media.Brushes.LimeGreen;
  line.StrokeThickness = new System.Windows.Length(1);
  lines[i] = line;
}

最後に、新しい線を毎回インスタンス化するのではなく、Do2DAnimation() メソッドを使用して線の配列を使用するように、コードを変更します。

//Line segmentAnimation = new Line();
Line segmentAnimation = lines[x];

アニメーションの追加

これで正常に機能するアプリケーションができましたが、線全体を一度にグラフに挿入するというアニメーションはあまり面白くありません。 ビジュアル エフェクトとしてはかなり稚拙です。 2つの座標の間を線が実際に描かれていくというアニメーションを作成し、はるかにスムーズなビジュアル エフェクトを実現したいと思います。 WPF の 2D アニメーション インフラストラクチャを使用すれば、この種のアニメーションは非常に簡単に作成できます。 基本的な知識については、animation in the WinFX SDK (英語) を参照してください。

以下では、これらの線をアニメーション化した方法を説明します。 まず、ビジュアル ツリーに線が追加されたときに、点が 1 つだけ描かれるように、X2 と Y2 を X1 と Y1 と同一に変更します。 次に、実際の X2 と Y2 の値を使用して、WPF アニメーションを作成します。 System.Windows.Media.Animation ネームスペースから、2 つの DoubleAnimation クラスを作成する必要があります。 作成するのが、DoubleAnimation クラスであることがなぜわかったのか不思議に思われるかもしれません。 それは、アニメーション化する値 「X2 と Y2」のデータ型がどちらも Double 型だったからです。 System.Windows.Media.Animation ネームスペースを参照すると、ByteAnimationBooleanAnimation などのさまざまな多くのオブジェクト タイプが、特定のアニメーション クラスであることがわかります。 これらの Animation クラスはすべて、AnimationTimeline 抽象クラスから派生し、あらゆる種類のアニメーションを行うための共通のパラダイムとなります。 最初はこの方法でアニメーションを作成するのはわかりにくいように感じますが、WPF に慣れるにつれ、わかりやすくなりました。 WPF アニメーションにはこの共通パラダイムがあるので、WPF をいったん理解してしまえば、あらゆるものをアニメーション化でき、スキルを別のアプリケーションで再利用できます。

そこでアニメーションを作成するには、DoubleAnimation クラスにいくつかプロパティを設定した後、それらを線自体に関連付けます。 通常、アニメーション クラスは、FromToBy のプロパティをサポートします。これらは、from の値から to の値まで by の値だけアニメーションを作成するための構文として使用されます。 この例では、DoubleAnimation のコンストラクタで、線の終点を基に To 値だけを設定します。 From と By の値は、自動的に設定されます。 また Duration プロパティを渡して、アニメーションの時間の長さを宣言します。 この例では、Duration が 0.5 秒に設定されているので、アニメーションがタイマと同期します。

これらのプロパティを DoubleAnimation クラスに設定したところで、今度はこのアニメーションの特定のインスタンスを作成する必要があります。 これには、アニメーションの CreateClock() メソッドを呼び出します。 次に、ユーザー インターフェイスの特定の FrameworkElement、この例では Line にそのクロックを適用します。これには、ApplyAnimationClock() メソッドを使用し、Line.X2Property など、アニメーション化するプロパティを指定します。 ApplyAnimationClock() は、アニメーション化する対象である依存プロパティ (この例では Line.X2PropertyLine.Y2Property) とアニメーションから作成したクロックの 2 つの引数を取ります。 作成するアニメーションを連動させることによって、クロック自体をその ApplyAnimationClock() プロパティを操作して制御できます。

これらの線をリサイクルするので、追加する前にヌルに設定してアニメーションを消去する必要があります。

作成されたコードは次のとおりです。

//X へのアニメーションの追加
//X へのアニメーションの追加
segmentAnimationX = new DoubleAnimation((x * 10) + 10, new Duration(TIME_SPAN));
//以前のアニメーションをヌルに変更
segment.ApplyAnimationClock(Line.X2Property, null); 
clockSegmentX = segmentAnimationX.CreateClock();
segment.ApplyAnimationClock(Line.X2Property, clockSegmentX); 
 
//Y へのアニメーションの追加
segmentAnimationY = new DoubleAnimation(100 - cpuInt, new Duration(TIME_SPAN));
//以前のアニメーションをヌルに変更
segment.ApplyAnimationClock(Line.Y2Property, null);
clockSegmentY = segmentAnimationY.CreateClock();
segment.ApplyAnimationClock(Line.Y2Property, clockSegmentY);
 
 
//線の挿入とアニメーションの開始
CpuGraphAnimation2d.Children.Insert(0, segment);
clockSegmentX.Controller.Begin();
clockSegmentY.Controller.Begin();

いかがですか。 単に線を挿入するだけの無味乾燥なテクニックに比べ、アニメーション化した線ははるかにスムーズです。

アニメーション化した棒グラフの追加

線グラフができあがったところで、タスク マネージャに表示されたグラフを棒グラフに変換してみましょう。 ここでも、WPF アニメーションを使用すれば、タスクマネージャが四角を単に再表示するのではなく、四角を縮小拡大してタスク マネージャのエクスペリエンスを改善できます。 また、四角を少し透明にして、ビジュアル効果を高めましょう。

棒グラフを作成するには、Rectangle (四角) 図形を使用すればほぼ完璧です。 しかし Rectangle には注意が必要です。 作成するアニメーションでは、棒が下から上へ垂直に伸びるように作成したいと考えています。 しかしながら、WPF の座標軸は、Y 軸方向は下へ、X 軸方向は右へと動きます。 したがって、アニメーションが下から上へ動くようにするには、四角を回転させて配置する必要があります。 WPF には、標準の変形クラスを使用してこの操作を行う便利なクラスがあり、ビジュアル ツリーの任意の要素に適用できます この例では、RotateTransform クラスを使用して、四角を 180 度回転させ、キャンバス上に配置します。 そこで、初期化ルーチン内に、適切な回転と変形操作を作成し、それを変形コレクションに追加し、四角を作成し、RenderTransform メソッドを使用して変形をレンダリングし、最後に、四角をビジュアル ツリーに追加します。 結局のところ、四角形のアニメーション化は、線のアニメーション化と非常によく似ています。 ここでも DoubleAnimation を使用してそれを RectangleWidth プロパティに適用します。四角を 180 度回転させたことに注意してください。

ここで完成のはずです。なのに、なぜここでいったん停止するのでしょう。 2D の代わりに 3D バーのアニメーションを作成し、このアプリケーションを 3D を使用して改善したいと考えています。 Viewport3D は、2D キャンバスの上に配置します。

Viewport3D は、OrthographicCamera を使用して、ビューポート内に配置されたモデルを参照します。 高さを変化させた後に固定しておくので、PerspectiveCamera の代わりに OrthographicCamera を使用することにします。 DirectionalLight を 1 つだけ追加して、グラフに照明を当てます。 また、空の ModelVisual3D を提供して、これにコード経由で円筒を追加します。 作成する 3D 環境を設定する XAML は次のとおりです。

<Viewport3D>
  <Viewport3D.Camera>
        <OrthographicCamera 
          Width="2.5"
          UpDirection="0,1,0"
          Position="0.0,-0.2,-5.0"
          LookDirection="0,0.05,1"
            />
      </Viewport3D.Camera>
      <ModelVisual3D>
        <ModelVisual3D.Content>
          <Model3DGroup >
            <DirectionalLight Color="White" Direction="-7, -4, -10" />
          </Model3DGroup>
        </ModelVisual3D.Content>
      </ModelVisual3D>
      <ModelVisual3D/>
    </Viewport3D>

円筒を追加するために、Mesh3DObjects というクラスを使用しました。これは、WPF チームの開発者が作成したクラスですが、正式にクラス ライブラリには含まれていません。 このクラスは、3D 空間で使用するプリミティブのセットを提供します (このクラスには、球や円環面など、他のプリミティブも用意されています)。 円筒をどうして XAML で追加しないのか不思議に思われるかもしれません。 そうすることも可能ですが、それには、クラスを別のコンポーネントとしてコンパイルし、そのクラスを XAML 内で宣言し、シリンダーをマークアップによって追加する必要があります。しかし、その代わりに円筒をプログラムによって追加できます。 この文書に付属のサンプル プロジェクトにこのクラス (Mesh3DObjects.cs) が含まれているので、図形がどのように作成されたかを確認してください。

円筒をコードでどのように作成するかを説明しましょう。 まずスタートアップ ルーチンで、プリミティブのクラスにある円筒のファクトリ クラスを作成して、円筒を作成します。 次に、ファクトリから特定の円筒を作成し、その特定の円筒のブラシ素材としてこの例では緑の SolidColorBrush を提供します。次に、ScaleTranform3D を使用して円筒を変形し、円筒の Y の最初の値が 0 になるように円筒のサイズを変更します。

//初期の 3d シリンダの追加
Mesh3DObjects.Cylinder cylinderFactory = new Mesh3DObjects.Cylinder();
Material materialGreen = new DiffuseMaterial(new SolidColorBrush(Colors.LimeGreen));
cylinder = new GeometryModel3D(cylinderFactory.Mesh, materialGreen);
ModelVisual3D mv3d = CpuPumpAnimation3dViewPort.Children[1] as ModelVisual3D;
mv3d.Content = cylinder;

後は 3D オブジェクトをアニメーション化すれば終わりです。 WPF アニメーション プラットフォームの優れたところは、3D をアニメーション化するためのテクニックが、2D のアニメーション化と同じである点です。 円筒のサイズを変更するには、メッシュの ScaleTransform3D プロパティを使用する必要があります。 ScaleTransform3DVector3D の 1 つのタイプなので、Vector3DAnimation を作成します。 2D 空間と同様、メッシュの ScaleTransform3D.ScaleYProperty 依存プロパティをアニメーション化します。 この例では、Y=1 の場合、円筒が 100 % になります。 したがって、CPU 使用率を表す Y の値に .01 を掛ければ相対値が得られ、それが To 値によって表されます。 From 値は、cpuInt に .01 を掛けた値です。

また、円筒が上方向に伸びていくように、この変形の ScaleCenter の Y の値を -1 に指定する必要があります。 これは直観的にわかりにくいかもしれませんが、ScaleTransformScaleCenter を設定しなければ、円筒が上下の両方向から伸びてきます。 ここで設定したいアニメーションは、上方向のみに「成長する」動きなので、ScaleCenter を設定する必要があります。

以前のアニメーションを消去してから、新しいアニメーションを追加して、コレクションを追加します。 これでできあがりです。

private void Do3DAnimation()
{
 
    vector3DAnimation = new DoubleAnimation();
    vector3DAnimation.From = (double)(y * .01);
    vector3DAnimation.To = (double)(cpuInt * .01);
    vector3DAnimation.Duration = new Duration(TIME_SPAN);
    //スケール センターを y = -1 に設定
    scaleTransform3D.CenterY = -1; 
    clock3D = vector3DAnimation.CreateClock();
    scaleTransform3D.ApplyAnimationClock(ScaleTransform3D.ScaleYProperty,clock3D);
    ModelVisual3D mv3d = CpuPumpAnimation3dViewPort.Children[1] as ModelVisual3D;
    mv3d.Transform = scaleTransform3D;
    clock3D.Controller.Begin();
    CpuPumpAnimation3dViewPort.Visibility = Visibility.Visible;
 
}
 

これで、動的にアニメーション化された 3D メッシュができました。

AVALON2D-3D_FIG1.JPG

まとめ

このアプリケーションは、広く応用できます。 タスク マネージャやパフォーマンス モニタをすべて WPF で作成することも可能です。 または、たとえば、WCF Web サービスなどを使用して、他のデータ ソースからグラフを作成することもできます。 WPF には、目を引くデータ ビジュアライゼーションのための方法が数多く用意されているのです。

謝辞

Vista の高度なアクセス許可について支援してくれた Catherine Heller に感謝します。

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