WPF-クイックガイド

WPFは、Windows PresentationFoundationの略です。これは、Windowsアプリケーションを構築するための強力なフレームワークです。このチュートリアルでは、WPFアプリケーションを構築するために理解する必要のある機能と、それがWindowsアプリケーションに根本的な変更をもたらす方法について説明します。

WPFは最初に.NETFramework 3.0バージョンで導入され、その後、他の多くの機能が後続の.NETFrameworkバージョンで追加されました。

WPFアーキテクチャ

WPF以前は、MFCやWindowsフォームなどのMicrosoftが提供する他のユーザーインターフェイスフレームワークは、User32およびGDI32 DLLの単なるラッパーでしたが、WPFはUser32を最小限しか使用していませんでした。そう、

  • WPFは単なるラッパーではありません。
  • これは.NETフレームワークの一部です。
  • これには、マネージドコードとアンマネージドコードが混在しています。

WPFアーキテクチャの主要なコンポーネントは、次の図に示すとおりです。WPFの最も重要なコード部分は次のとおりです。

  • プレゼンテーションフレームワーク
  • プレゼンテーションコア
  • Milcore

ザ・ presentation framework そしてその presentation core マネージコードで書かれています。 Milcore は、DirectX(表示とレンダリングを担当)との緊密な統合を可能にするアンマネージコードの一部です。 CLR メモリ管理、エラー処理などの多くの機能を提供することにより、開発プロセスの生産性を高めます。

WPF –利点

以前のGUIフレームワークでは、アプリケーションの外観と動作の間に実際の分離はありませんでした。GUIと動作の両方が同じ言語で作成されました。たとえば、C#やVB.Netは、UIとそれに関連する動作の両方を実装するために、開発者のより多くの労力を必要とします。

WPFでは、UI要素はXAMLで設計されていますが、動作はC#やVB.Netなどの手続き型言語で実装できます。したがって、動作をデザイナコードから分離するのは非常に簡単です。

XAMLを使用すると、プログラマーはデザイナーと並行して作業できます。GUIとその動作を分離することで、スタイルとテンプレートを使用してコントロールの外観を簡単に変更できます。

WPF –機能

WPFは、Windowsアプリケーションを作成するための強力なフレームワークです。それは多くの素晴らしい機能をサポートし、そのうちのいくつかは以下にリストされています-

特徴 説明
コントロール内のコントロール 別のコントロール内のコントロールをコンテンツとして定義できます。
データバインディング ユーザーインターフェイス上のUI要素とデータオブジェクト間のデータを表示および操作するメカニズム。
メディアサービス 画像、オーディオ、ビデオなどの一般的なメディア要素を使用してユーザーインターフェイスを構築するための統合システムを提供します。
テンプレート WPFでは、テンプレートを使用して要素の外観を直接定義できます。
アニメーション ユーザーインターフェイスでの双方向性と動きの構築
代替入力 Windows7以降でマルチタッチ入力をサポートします。
Direct3D より複雑なグラフィックやカスタムテーマを表示できます

Microsoftは、WPFアプリケーション開発のための2つの重要なツールを提供しています。

  • Visual Studio
  • Expression Blend

どちらのツールもWPFプロジェクトを作成できますが、実際には、Visual Studioは開発者によってより多く使用され、Blendは設計者によってより頻繁に使用されます。このチュートリアルでは、主にVisualStudioを使用します。

インストール

Microsoftは、VisualStudioからダウンロードできる無料バージョンのVisualStudioを提供しています。

ファイルをダウンロードし、以下の手順に従って、システムにWPFアプリケーション開発環境をセットアップします。

  • ダウンロードが完了したら、 installer。次のダイアログが表示されます。

  • クリック Install ボタンをクリックすると、インストールプロセスが開始されます。

  • インストールプロセスが正常に完了すると、次のダイアログボックスが表示されます。

  • このダイアログボックスを閉じ、必要に応じてコンピュータを再起動します。

  • 次に、スタートメニューからVisual Studioを開き、次のダイアログボックスを開きます。

  • すべてが完了すると、VisualStudioのメインウィンドウが表示されます。

これで、最初のWPFアプリケーションを構築する準備が整いました。

この章では、簡単なHello WorldWPFアプリケーションを開発します。それでは、以下の手順に従って簡単な実装を始めましょう。

  • [ファイル]> [新規]> [プロジェクト]メニューオプションをクリックします。
  • 以下のダイアログボックスが表示されます。
  • [テンプレート]で[VisualC#]を選択し、中央のパネルで[WPFアプリケーション]を選択します。

  • プロジェクトに名前を付けます。タイプHelloWorld 名前フィールドで、[OK]ボタンをクリックします。

  • デフォルトでは、2つのファイルが作成されます。1つは XAML ファイル(mainwindow.xaml)ともう1つは CS ファイル(mainwindow.cs)

  • mainwindow.xamlに、2つのサブウィンドウが表示されます。1つは design window もう1つは source (XAML) window

  • WPFアプリケーションでは、アプリケーションのUIを設計する方法が2つあります。1つは、UI要素をツールボックスからデザインウィンドウにドラッグアンドドロップするだけです。2番目の方法は、UI要素のXAMLタグを記述してUIを設計することです。ドラッグアンドドロップ機能がUIデザインに使用される場合、VisualStudioはXAMLタグを処理します。

  • mainwindow.xamlファイルには、デフォルトで次のXAMLタグが書き込まれます。

<Window x:Class = "HelloWorld.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid> 
   </Grid> 
	
</Window>
  • デフォルトでは、グリッドはページの後の最初の要素として設定されます。
  • ツールボックスに移動して、TextBlockをデザインウィンドウにドラッグしましょう。
  • デザインウィンドウにTextBlockが表示されます。
  • ソースウィンドウを見ると、VisualStudioがTextBlockのXAMLコードを生成していることがわかります。

  • XAMLコードのTextBlockのTextプロパティをTextBlockからHelloWorldに変更してみましょう。

<Window x:Class = "HelloWorld.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <TextBlock x:Name = "textBlock" HorizontalAlignment = "Left"
         Margin = "235,143,0,0" TextWrapping = "Wrap" Text = "Hello World!"
         VerticalAlignment = "Top" Height = "44" Width = "102" /> 
   </Grid> 
	
</Window>
  • これで、デザインウィンドウにも変更が表示されます。

上記のコードをコンパイルして実行すると、次のウィンドウが表示されます。

おめでとう!これで、最初のWPFアプリケーションが設計および作成されました。

WPFの操作中に最初に遭遇するものの1つは、XAMLです。XAMLはExtensibleApplication MarkupLanguageの略です。これは、XMLに基づく単純で宣言型の言語です。

  • XAMLでは、階層関係を持つオブジェクトのプロパティを作成、初期化、および設定するのは非常に簡単です。

  • これは主にGUIの設計に使用されますが、Workflow Foundationでワークフローを宣言するなど、他の目的にも使用できます。

基本構文

新しいWPFプロジェクトを作成すると、以下に示すように、MainWindow.xamlにデフォルトでいくつかのXAMLコードが表示されます。

<Window x:Class = "Resources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
         
   </Grid> 
	
</Window>

上記のXAMLファイルには、さまざまな種類の情報が含まれています。次の表は、各情報の役割を簡単に説明しています。

情報 説明
<ウィンドウ これは、ルートの開始オブジェクト要素またはコンテナです。
x:Class = "Resources.MainWindow" これは、マークアップを背後で定義された部分クラスコードに接続する部分クラス宣言です。
xmlns = "http://schemas.microsoft.com/win fx / 2006 / xaml / presentation" WPFクライアント/フレームワークのデフォルトのXAML名前空間をマップします
xmlns:x = "http://schemas.microsoft.com/w infx / 2006 / xaml" xにマップするXAML言語のXAML名前空間:プレフィックス
>> ルートのオブジェクト要素の終わり

<グリッド>

</グリッド>

空のグリッドオブジェクトのタグを開始および終了しています。
</ウィンドウ> オブジェクト要素を閉じる

XAMLの構文規則は、XMLとほぼ同じです。XAMLドキュメントを見ると、実際には有効なXMLファイルであることがわかりますが、XMLファイルは必ずしもXAMLファイルである必要はありません。これは、XMLでは属性の値が文字列である必要があるのに対し、XAMLではプロパティ要素構文と呼ばれる別のオブジェクトである可能性があるためです。

  • Object要素の構文は、左山括弧(<)で始まり、その後にオブジェクトの名前が続きます(例:Button)。

  • そのオブジェクト要素のいくつかのプロパティと属性を定義します。

  • Object要素は、スラッシュ(/)の直後に直角ブラケット(>)を付けて閉じる必要があります。

子要素のない単純なオブジェクトの例

<Button/>

いくつかの属性を持つオブジェクト要素の例

<Button Content = "Click Me" Height = "30" Width = "60" />

代替構文の例はプロパティを定義します(プロパティ要素構文)

<Button> 
   <Button.Content>Click Me</Button.Content> 
   <Button.Height>30</Button.Height> 
   <Button.Width>60</Button.Width> 
</Button>

子要素を持つオブジェクトの例:StackPanelには子要素としてTextblockが含まれています

<StackPanel Orientation = "Horizontal"> 
   <TextBlock Text = "Hello"/> 
</StackPanel>

WPFでXAMLを使用する理由

XAMLは、WPFの最も広く知られている機能であるだけでなく、最も誤解されている機能の1つでもあります。WPFに触れている場合は、XAMLについて聞いたことがあるはずです。ただし、XAMLに関する次の2つのあまり知られていない事実に注意してください-

  • WPFはXAMLを必要としません
  • XAMLはWPFを必要としません

実際、これらは分離可能なテクノロジーです。それがどのようになり得るかを理解するために、XAMLのいくつかのプロパティを使用してボタンが作成される簡単な例を見てみましょう。

<Window x:Class = "WPFXAMLOverview.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <Button x:Name = "button" Content = "Click Me" HorizontalAlignment = "Left"  
         Margin = "150" VerticalAlignment = "Top" Width = "75" /> 
   </StackPanel> 
	
</Window>

WPFでXAMLを使用しないことを選択した場合は、手続き型言語でも同じGUI結果を得ることができます。同じ例を見てみましょうが、今回はC#でボタンを作成します。

using System.Windows; 
using System.Windows.Controls;  

namespace WPFXAMLOverview { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
			
         // Create the StackPanel 
         StackPanel stackPanel = new StackPanel(); 
         this.Content = stackPanel; 
			
         // Create the Button 
         Button button = new Button();
         button.Content = "Click Me"; 
         button.HorizontalAlignment = HorizontalAlignment.Left; 
         button.Margin = new Thickness(150); 
         button.VerticalAlignment = VerticalAlignment.Top; 
         button.Width = 75; 
         stackPanel.Children.Add(button);  
      } 
   } 
}

XAMLコードまたはC#コードのいずれかをコンパイルして実行すると、以下に示すのと同じ出力が表示されます。

上記の例から、オブジェクトのプロパティを作成、初期化、および設定するためにXAMLで実行できることは、コードを使用して同じタスクを実行できることは明らかです。

  • XAMLは、UI要素を設計するためのもう1つのシンプルで簡単な方法です。

  • XAMLでは、UI要素を設計するためにできることが唯一の方法であるという意味ではありません。XAMLでオブジェクトを宣言するか、コードを使用してオブジェクトを定義できます。

  • XAMLはオプションですが、それにもかかわらず、XAMLはWPF設計の中心です。

  • XAMLの目標は、ビジュアルデザイナーがユーザーインターフェイス要素を直接作成できるようにすることです。

  • WPFは、マークアップからユーザーインターフェイスのすべての視覚的側面を制御できるようにすることを目的としています。

プログラマーがオブジェクトを簡単に処理し、アプリケーションの動作を変更できるように、要素とコンポーネントがツリー構造で順序付けられている多くのテクノロジーがあります。Windows Presentation Foundation(WPF)には、オブジェクトの形式の包括的なツリー構造があります。WPFでは、完全なオブジェクトツリーを概念化する方法が2つあります。

  • 論理ツリー構造
  • ビジュアルツリー構造

これらのツリー構造を使用すると、UI要素間の関係を簡単に作成および識別できます。ほとんどの場合、WPFの開発者と設計者は、手続き型言語を使用してアプリケーションを作成するか、オブジェクトツリー構造を念頭に置いてXAMLでアプリケーションのUI部分を設計します。

論理ツリー構造

WPFアプリケーションでは、XAMLのUI要素の構造は論理ツリー構造を表します。XAMLでは、UIの基本要素は開発者によって宣言されます。WPFの論理ツリーでは、次のように定義されています。

  • 依存関係のプロパティ
  • 静的および動的リソース
  • その名前などの要素をバインドします。

ボタンとリストボックスが作成される次の例を見てみましょう。

<Window x:Class = "WPFElementsTree.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <Button x:Name = "button" Height = "30" Width = "70" Content = "OK" Margin = "20" /> 
		
      <ListBox x:Name = "listBox" Height = "100" Width = "100" Margin = "20"> 
         <ListBoxItem Content = "Item 1" /> 
         <ListBoxItem Content = "Item 2" /> 
         <ListBoxItem Content = "Item 3" /> 
      </ListBox> 
		
   </StackPanel> 
	
</Window>

XAMLコードを見ると、ツリー構造がわかります。つまり、ルートノードはウィンドウであり、ルートノード内にはStackPanelという子が1つだけあります。ただし、StackPanelには、ボタンとリストボックスの2つの子要素が含まれています。リストボックスには、さらに3つの子リストボックスアイテムがあります。

ビジュアルツリー構造

WPFでは、ビジュアルツリーの概念は、Visual BaseClassで表されるビジュアルオブジェクトの構造を記述します。これは、出力画面にレンダリングされるすべてのUI要素を意味します。

プログラマーが特定のコントロールのテンプレートを作成したい場合、実際にはそのコントロールのビジュアルツリーをレンダリングしています。ビジュアルツリーは、パフォーマンスと最適化の理由から、より低いレベルのコントロールを描画したい場合にも非常に役立ちます。

WPFアプリケーションでは、ビジュアルツリーは次の目的で使用されます。

  • ビジュアルオブジェクトのレンダリング。
  • レイアウトのレンダリング。
  • ルーティングされたイベントは、ほとんどの場合、論理ツリーではなく、ビジュアルツリーに沿って移動します。

ボタンとリストボックスを含む上記の単純なアプリケーションのビジュアルツリーを表示するには、XAMLコードをコンパイルして実行すると、次のウィンドウが表示されます。

アプリケーションの実行中は、以下に示すように、このアプリケーションの完全な階層を示すライブビジュアルツリーウィンドウに、実行中のアプリケーションのビジュアルツリーが表示されます。

ビジュアルツリーは通常、論理ツリーのスーパーセットです。ここで、すべての論理要素がビジュアルツリーにも存在することがわかります。したがって、これら2つのツリーは、実際にはUIを構成する同じオブジェクトセットの2つの異なるビューにすぎません。

  • 論理ツリーでは多くの詳細が省略されているため、ユーザーインターフェイスのコア構造に焦点を当て、それがどのように表示されているかの詳細を無視できます。

  • 論理ツリーは、ユーザーインターフェイスの基本構造を作成するために使用するものです。

  • プレゼンテーションに集中している場合は、ビジュアルツリーが役立ちます。たとえば、UI要素の外観をカスタマイズする場合は、ビジュアルツリーを使用する必要があります。

WPFアプリケーションでは、依存関係プロパティは、CLRプロパティを拡張する特定の種類のプロパティです。これは、WPFプロパティシステムで利用可能な特定の機能を利用します。

依存関係プロパティを定義するクラスは、から継承する必要があります DependencyObjectクラス。XAMLで使用されるUIコントロールクラスの多くは、DependencyObject クラスとそれらは依存関係プロパティをサポートします。たとえば、Buttonクラスは IsMouseOver 依存関係プロパティ。

次のXAMLコードは、いくつかのプロパティを持つボタンを作成します。

<Window x:Class = "WPFDependencyProperty.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFDependencyProperty"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button  Height = "40" Width = "175" Margin = "10" Content = "Dependency Property"> 
         <Button.Style> 
            <Style TargetType = "{x:Type Button}"> 
               <Style.Triggers> 
					
                  <Trigger Property = "IsMouseOver" Value = "True"> 
                     <Setter Property = "Foreground" Value = "Red" /> 
                  </Trigger>
						
               </Style.Triggers>
            </Style> 
         </Button.Style> 
      </Button> 
   </Grid> 
	
</Window>

XAMLのx:Typeマークアップ拡張機能には、C#のtypeof()と同様の機能があります。<Style TargetType = "{x:TypeButton}">などのオブジェクトのタイプをとる属性が指定されている場合に使用されます。

上記のコードをコンパイルして実行すると、次のようになります。 MainWindow。マウスをボタンの上に置くと、ボタンの前景色が変わります。マウスがボタンを離れると、元の色に戻ります。

依存関係プロパティが必要な理由

依存関係プロパティは、アプリケーションで使用するときにあらゆる種類の利点を提供します。依存関係プロパティは、次のシナリオでCLRプロパティに対して使用できます-

  • スタイルを設定したい場合
  • データバインディングが必要な場合
  • リソース(静的または動的リソース)で設定する場合
  • アニメーションをサポートしたい場合

基本的に、依存関係プロパティは、CLRプロパティを使用しても得られない多くの機能を提供します。

の主な違い dependency properties およびその他 CLR properties 以下にリストされています-

  • CLRプロパティは、を使用してクラスのプライベートメンバーから直接読み取り/書き込みできます。 getter そして setter。対照的に、依存関係プロパティはローカルオブジェクトに格納されません。

  • 依存関係プロパティは、DependencyObjectクラスによって提供されるキーと値のペアのディクショナリに格納されます。また、変更時にプロパティを保存するため、多くのメモリを節約できます。XAMLでもバインドできます。

カスタム依存関係プロパティ

.NET Frameworkでは、カスタムの依存関係プロパティも定義できます。以下の手順に従って、C#でカスタム依存関係プロパティを定義します。

  • 宣言して登録する dependency property システムコールレジスタ付き。

  • 提供する setter そして getter プロパティのために。

  • を定義する static handler グローバルに発生するすべての変更を処理します

  • を定義する instance handler これは、その特定のインスタンスに発生するすべての変更を処理します。

次のC#コードは、依存関係プロパティを定義して、 SetText ユーザーコントロールのプロパティ。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes;  

namespace WpfApplication3 { 
   /// <summary> 
      /// Interaction logic for UserControl1.xaml 
   /// </summary> 
	
   public partial class UserControl1 : UserControl { 
	
      public UserControl1() { 
         InitializeComponent(); 
      }
		
      public static readonly DependencyProperty SetTextProperty = 
         DependencyProperty.Register("SetText", typeof(string), typeof(UserControl1), new 
            PropertyMetadata("", new PropertyChangedCallback(OnSetTextChanged))); 
				
      public string SetText { 
         get { return (string)GetValue(SetTextProperty); } 
         set { SetValue(SetTextProperty, value); } 
      } 
		
      private static void OnSetTextChanged(DependencyObject d,
         DependencyPropertyChangedEventArgs e) { 
         UserControl1 UserControl1Control = d as UserControl1; 
         UserControl1Control.OnSetTextChanged(e); 
      } 
		
      private void OnSetTextChanged(DependencyPropertyChangedEventArgs e) { 
         tbTest.Text = e.NewValue.ToString(); 
      }  
   } 
}

これは、TextBlockがユーザーコントロールとして定義され、TextプロパティがSetText依存関係プロパティによって割り当てられるXAMLファイルです。

次のXAMLコードは、ユーザーコントロールを作成し、そのコントロールを初期化します。 SetText 依存関係プロパティ。

<Window x:Class = "WpfApplication3.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:views = "clr-namespace:WpfApplication3"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <views:UserControl1 SetText = "Hellow World"/> 
   </Grid> 
	
</Window>

このアプリケーションを実行してみましょう。MainWindowで、ユーザーコントロールの依存関係プロパティがテキストとして正常に使用されていることがすぐにわかります。

A routed eventは、イベントを発生させたオブジェクトだけでなく、要素ツリー内の複数のリスナーでハンドラーを呼び出すことができるタイプのイベントです。これは基本的に、RoutedEventクラスのインスタンスによってサポートされるCLRイベントです。WPFイベントシステムに登録されています。RoutedEventsには、次の3つの主要なルーティング戦略があります。

  • 直接イベント
  • バブリングイベント
  • トンネルイベント

直接イベント

直接イベントは、イベントが発生した要素によって発生するWindowsフォームのイベントに似ています。

標準のCLRイベントとは異なり、直接ルーティングされたイベントはクラス処理をサポートし、カスタムコントロールのスタイル内のイベントセッターおよびイベントトリガーで使用できます。

直接イベントの良い例は、MouseEnterイベントです。

バブリングイベント

バブリングイベントは、イベントが発生した要素から始まります。次に、ビジュアルツリーを上ってビジュアルツリーの最上位の要素に移動します。したがって、WPFでは、最上位の要素はおそらくウィンドウです。

トンネルイベント

要素ツリールートのイベントハンドラーが呼び出され、イベントは、イベントが発生した要素に到達するまで、ビジュアルツリーを下ってすべての子ノードに移動します。

バブリングイベントとトンネリングイベントの違いは、トンネリングイベントは常にプレビューで開始されることです。

WPFアプリケーションでは、イベントはトンネリング/バブリングのペアとして実装されることがよくあります。したがって、MouseDownのプレビューとMouseDownイベントがあります。

以下に示すのは、いくつかのプロパティとイベントを使用してボタンと3つのテキストブロックが作成されるルーティングイベントの簡単な例です。

<Window x:Class = "WPFRoutedEvents.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "450" Width = "604" ButtonBase.Click  = "Window_Click" >
	
   <Grid> 
      <StackPanel Margin = "20" ButtonBase.Click = "StackPanel_Click">
		
         <StackPanel Margin = "10"> 
            <TextBlock Name = "txt1" FontSize = "18" Margin = "5" Text = "This is a TextBlock 1" /> 
            <TextBlock Name = "txt2" FontSize = "18" Margin = "5" Text = "This is a TextBlock 2" /> 
            <TextBlock Name = "txt3" FontSize = "18" Margin = "5" Text = "This is a TextBlock 3" /> 
         </StackPanel> 
			
         <Button Margin = "10" Content = "Click me" Click = "Button_Click" Width = "80"/> 
      </StackPanel> 
   </Grid> 
	
</Window>

Button、StackPanel、およびWindowのClickイベント実装のC#コードを次に示します。

using System.Windows; 
 
namespace WPFRoutedEvents { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary>
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
      }  
		
      private void Button_Click(object sender, RoutedEventArgs e) { 
         txt1.Text = "Button is Clicked"; 
      } 
		
      private void StackPanel_Click(object sender, RoutedEventArgs e) { 
         txt2.Text = "Click event is bubbled to Stack Panel"; 
      } 
		
      private void Window_Click(object sender, RoutedEventArgs e) { 
         txt3.Text = "Click event is bubbled to Window"; 
      }
		
   } 
}

上記のコードをコンパイルして実行すると、次のウィンドウが表示されます-

ボタンをクリックすると、以下に示すように、テキストブロックが更新されます。

ルーティングされたイベントを特定のレベルで停止する場合は、e.Handled = true;を設定する必要があります。

変更しましょう StackPanel_Click 以下に示すイベント-

private void StackPanel_Click(object sender, RoutedEventArgs e) { 
   txt2.Text = "Click event is bubbled to Stack Panel"; 
   e.Handled = true; 
}

ボタンをクリックすると、クリックイベントがウィンドウにルーティングされず、スタックパネルで停止し、3番目のテキストブロックが更新されないことがわかります。

カスタムルーティングイベント

.NET Frameworkでは、カスタムルーティングイベントを定義することもできます。C#でカスタムルーティングイベントを定義するには、以下の手順に従う必要があります。

  • ルーティングされたイベントを宣言し、システムコールRegisterRoutedEventで登録します。

  • ルーティング戦略、つまりバブル、トンネル、またはダイレクトを指定します。

  • イベントハンドラーを提供します。

カスタムルーティングイベントの詳細を理解するために例を見てみましょう。以下の手順に従ってください-

  • WPFCustomRoutedEventを使用して新しいWPFプロジェクトを作成します

  • ソリューションを右クリックして、[追加]> [新しいアイテム...]を選択します。

  • 次のダイアログが開きます。次に選択します。 Custom Control (WPF) 名前を付けます MyCustomControl

  • クリック Add ボタンをクリックすると、2つの新しいファイル(Themes / Generic.xamlとMyCustomControl.cs)がソリューションに追加されることがわかります。

次のXAMLコードは、Generic.xamlファイルのカスタムコントロールのスタイルを設定します。

<ResourceDictionary 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFCustomRoutedEvent">
	
   <Style TargetType = "{x:Type local:MyCustomControl}"> 
      <Setter Property = "Margin" Value = "50"/> 
      <Setter Property = "Template"> 
         <Setter.Value> 
            <ControlTemplate TargetType = "{x:Type local:MyCustomControl}">
				
               <Border Background = "{TemplateBinding Background}" 
                  BorderBrush = "{TemplateBinding BorderBrush}" 
                  BorderThickness = "{TemplateBinding BorderThickness}"> 
                  <Button x:Name = "PART_Button" Content = "Click Me" /> 
               </Border> 
					
            </ControlTemplate> 
         </Setter.Value> 
      </Setter> 
   </Style> 
	
</ResourceDictionary>

以下に示すのは、のC#コードです。 MyCustomControl class から継承します Control class カスタムルーティングイベントClickがカスタムコントロール用に作成されます。

using System.Windows; 
using System.Windows.Controls;  

namespace WPFCustomRoutedEvent { 

   public class MyCustomControl : Control { 
	
      static MyCustomControl() { 
         DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), 
            new FrameworkPropertyMetadata(typeof(MyCustomControl))); 
      } 
		
      public override void OnApplyTemplate() { 
         base.OnApplyTemplate();
			
         //demo purpose only, check for previous instances and remove the handler first 
         var button  =  GetTemplateChild("PART_Button") as Button; 
         if (button ! =  null) 
         button.Click + =  Button_Click;  
      } 
		
      void Button_Click(object sender, RoutedEventArgs e) { 
         RaiseClickEvent(); 
      } 
		
      public static readonly RoutedEvent ClickEvent  =  
         EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, 
         typeof(RoutedEventHandler), typeof(MyCustomControl)); 
			
      public event RoutedEventHandler Click { 
         add { AddHandler(ClickEvent, value); } 
         remove { RemoveHandler(ClickEvent, value); } 
      } 
		
      protected virtual void RaiseClickEvent() { 
         RoutedEventArgs args = new RoutedEventArgs(MyCustomControl.ClickEvent); 
         RaiseEvent(args); 
      }
		
   } 
}

これは、ユーザーがクリックするとメッセージボックスを表示するC#でのカスタムルーティングイベントの実装です。

using System.Windows;  

namespace WPFCustomRoutedEvent { 
   // <summary> 
      // Interaction logic for MainWindow.xaml
   // </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
      }  
		
      private void MyCustomControl_Click(object sender, RoutedEventArgs e) { 
         MessageBox.Show("It is the custom routed event of your custom control"); 
      } 
		
   } 
}

これは、ルーティングされたイベントClickを使用してカスタムコントロールを追加するためのMainWindow.xamlの実装です。

<Window x:Class = "WPFCustomRoutedEvent.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFCustomRoutedEvent"
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <local:MyCustomControl Click = "MyCustomControl_Click" /> 
   </Grid> 
	
</Window>

上記のコードをコンパイルして実行すると、カスタムコントロールを含む次のウィンドウが生成されます。

カスタムコントロールをクリックすると、次のメッセージが表示されます。

Windows Presentation Foundation(WPF)を使用すると、開発者は視覚的に充実したUIベースのアプリケーションを簡単に構築および作成できます。

  • 他のUIフレームワークの従来のUI要素またはコントロールもWPFアプリケーションで拡張されています。

  • すべての標準WPFコントロールは、System.Windows.Controlsの一部であるツールボックスにあります。

  • これらのコントロールは、XAMLマークアップ言語で作成することもできます。

WPFコントロールの完全な継承階層は次のとおりです-

次の表には、後続の章で説明するコントロールのリストが含まれています。

シニア番号 コントロールと説明
1 ボタン

ユーザー入力に応答するコントロール

2 カレンダー

ユーザーが視覚的なカレンダー表示を使用して日付を選択できるようにするコントロールを表します。

3 チェックボックス

ユーザーが選択またはクリアできるコントロール。

4 コンボボックス

ユーザーが選択できるアイテムのドロップダウンリスト。

5 コンテキストメニュー

この要素内からユーザーインターフェイス(UI)を介してコンテキストメニューが要求されるたびに表示されるコンテキストメニュー要素を取得または設定します。

6 DataGrid

カスタマイズ可能なグリッドにデータを表示するコントロールを表します。

7 DatePicker

ユーザーが日付を選択できるようにするコントロール。

8 ダイアログ

アプリケーションは、ユーザーが重要な情報を収集または表示するのに役立つ追加のウィンドウを表示する場合もあります。

9 グリッドビュー

水平方向にスクロールできる行と列のアイテムのコレクションを表示するコントロール。

10 画像

画像を表示するコントロール。

11 ラベル

フォームにテキストを表示します。アクセスキーのサポートを提供します。

12 リストボックス

ユーザーが選択できるアイテムのインラインリストを表示するコントロール。

13 メニュー

コマンドおよびイベントハンドラーに関連付けられた要素を階層的に整理できるようにするWindowsメニューコントロールを表します。

14 PasswordBox

パスワードを入力するためのコントロール。

15 現れる

アプリケーションウィンドウの範囲内で、既存のコンテンツの上にコンテンツを表示します。

16 プログレスバー

バーを表示して進行状況を示すコントロール。

17 ラジオボタン

ユーザーがオプションのグループから単一のオプションを選択できるようにするコントロール。

18 ScrollViewer

ユーザーがコンテンツをパンおよびズームできるようにするコンテナーコントロール。

19 スライダー

ユーザーがThumbコントロールをトラックに沿って移動することにより、値の範囲から選択できるようにするコントロール。

20 TextBlock

テキストを表示するコントロール。

21 ToggleButton

2つの状態を切り替えることができるボタン。

22 ツールチップ

要素の情報を表示するポップアップウィンドウ。

23

最小化/最大化オプション、タイトルバー、境界線、閉じるボタンを提供するルートウィンドウ

24 サードパーティのコントロール

WPFアプリケーションでサードパーティのコントロールを使用します。

これらすべてのコントロールについて、その実装とともに1つずつ説明します。

コントロールのレイアウトは、アプリケーションの使いやすさにとって非常に重要で重要です。これは、アプリケーション内のGUI要素のグループを配置するために使用されます。レイアウトパネルを選択する際に考慮すべき特定の重要事項があります-

  • 子要素の位置
  • 子要素のサイズ
  • 重なり合う子要素を互いに重ねる

アプリケーションが異なる画面解像度でsedされる場合、コントロールの固定ピクセル配置は機能しません。XAMLは、GUI要素を適切な方法で配置するための豊富な組み込みレイアウトパネルのセットを提供します。最も一般的で人気のあるレイアウトパネルのいくつかは次のとおりです-

シニア番号 パネルと説明
1 スタックパネル

スタックパネルは、XAMLのシンプルで便利なレイアウトパネルです。スタックパネルでは、子要素は、方向プロパティに基づいて、水平方向または垂直方向に1行に配置できます。

2 ラップパネル

WrapPanelでは、子要素は、orientationプロパティに基づいて、左から右、または上から下の順序で配置されます。

3 ドックパネル

DockPanelは、子要素を水平方向または垂直方向に相互に配置するための領域を定義します。DockPanelを使用すると、子要素を上、下、右、左、中央に簡単にドッキングできます。Dock プロパティ。

4 キャンバスパネル

キャンバスパネルは、子要素を相対的な座標を使用して明示的に配置できる基本的なレイアウトパネルです。 Canvas 左、右、上、下などの任意の側。

5 グリッドパネル

グリッドパネルは、行と列で構成される柔軟な領域を提供します。グリッドでは、子要素を表形式で配置できます。

レイアウトのネストとは、別のレイアウト内でレイアウトパネルを使用することを意味します。たとえば、グリッド内にスタックパネルを定義します。この概念は、アプリケーションで複数のレイアウトを利用するために広く使用されています。次の例では、グリッド内でスタックパネルを使用します。

次のXAMLコードを見てみましょう。

<Window x:Class = "WPFNestingLayouts.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFNestingLayouts" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid Background = "AntiqueWhite"> 
      <Grid.RowDefinitions> 
         <RowDefinition Height = "*" /> 
         <RowDefinition Height = "*" /> 
         <RowDefinition Height = "*" /> 
         <RowDefinition Height = "*" /> 
         <RowDefinition Height = "*" /> 
      </Grid.RowDefinitions> 
		
      <Grid.ColumnDefinitions> 
         <ColumnDefinition Width = "*" /> 
      </Grid.ColumnDefinitions> 
		
      <Label Content = "Employee Info" FontSize = "15"
         FontWeight = "Bold" Grid.Column = "0" Grid.Row = "0"/> 
			
      <StackPanel Grid.Column = "0" Grid.Row = "1" Orientation = "Horizontal"> 
         <Label Content = "Name"  VerticalAlignment = "Center" Width = "70"/> 
         <TextBox Name = "txtName" Text = "Muhammad Ali" VerticalAlignment = "Center"
            Width = "200">
         </TextBox> 
      </StackPanel>
		
      <StackPanel Grid.Column = "0" Grid.Row = "2" Orientation = "Horizontal"> 
         <Label Content = "ID" VerticalAlignment = "Center" Width = "70"/> 
         <TextBox Name = "txtCity" Text = "421" VerticalAlignment = "Center"
            Width = "50">
         </TextBox> 
      </StackPanel>
		
      <StackPanel Grid.Column = "0" Grid.Row = "3" Orientation = "Horizontal"> 
         <Label Content = "Age" VerticalAlignment = "Center" Width = "70"/> 
         <TextBox Name = "txtState" Text = "32" VerticalAlignment = "Center"
            Width = "50"></TextBox> 
      </StackPanel> 
		
      <StackPanel Grid.Column = "0" Grid.Row = "4" Orientation = "Horizontal"> 
         <Label Content = "Title" VerticalAlignment = "Center" Width = "70"/> 
         <TextBox Name = "txtCountry" Text = "Programmer" VerticalAlignment = "Center"
            Width = "200"></TextBox> 
      </StackPanel> 
		
   </Grid> 
	
</Window>

上記のコードをコンパイルして実行すると、次のウィンドウが表示されます。

上記のサンプルコードを実行して、他のネストレイアウトを試すことをお勧めします。

Windows Presentation Foundation(WPF)は、アプリケーションがマウス、キーボード、タッチパネルなどのさまざまなデバイスから入力を取得できる強力なAPIを提供します。この章では、WPFアプリケーションで処理できる次の種類の入力について説明します。

シニア番号 入力と説明
1 マウス

MouseDown、MouseEnter、MouseLeaveなどのさまざまなタイプのマウス入力があります。

2 キーボード

KeyDown、KeyUp、TextInputなど、多くの種類のキーボード入力があります。

3 ContextMenuまたはRoutedCommands

RoutedCommandsは、よりセマンティックなレベルでの入力処理を可能にします。これらは実際には、新規、開く、コピー、切り取り、保存などの簡単な手順です。

4 マルチタッチ

Windows 7以降のバージョンには、複数のタッチセンシティブデバイスからの入力を受信する機能があります。WPFアプリケーションは、タッチが発生したときにイベントを発生させることにより、マウスやキーボードなどの他の入力としてタッチ入力を処理することもできます。

コマンドライン引数は、ユーザーが実行時に一連のパラメーターまたは値をWPFアプリケーションに渡すことができるメカニズムです。これらの引数は、外部からアプリケーションを制御するために非常に重要です。たとえば、コマンドプロンプトからWord文書を開きたい場合は、次のコマンドを使用できます。C:\> start winword word1.docx」と開きます word1.docx 資料。

コマンドライン引数は、スタートアップ関数で処理されます。以下は、コマンドライン引数をWPFアプリケーションに渡す方法を示す簡単な例です。名前を付けて新しいWPFアプリケーションを作成しましょうWPFCommandLine

  • 1つのテキストボックスをツールボックスからデザインウィンドウにドラッグします。

  • この例では、txtファイルのパスをコマンドラインパラメーターとしてアプリケーションに渡します。

  • プログラムはtxtファイルを読み取り、テキストボックスにすべてのテキストを書き込みます。

  • 次のXAMLコードは、テキストボックスを作成し、いくつかのプロパティで初期化します。

<Window x:Class = "WPFCommandLine.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFCommandLine" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
      <TextBox x:Name = "textBox" HorizontalAlignment = "Left"  
         Height = "180" Margin = "100" TextWrapping = "Wrap" 
         VerticalAlignment = "Top" Width = "300"/> 
   </Grid> 
	
</Window>
  • 次に、以下に示すように、App.xamlファイルでStartupイベントをサブスクライブします。
<Application x:Class = "WPFCommandLine.App" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local = "clr-namespace:WPFCommandLine" 
   StartupUri = "MainWindow.xaml" Startup = "app_Startup"> 
	
   <Application.Resources> 
          
   </Application.Resources>
	
</Application>
  • 以下に示すのは、コマンドライン引数を取得するApp.xaml.csのapp_Startupイベントの実装です。

using System.Windows;
  
namespace WPFCommandLine { 
   /// <summary> 
      /// Interaction logic for App.xaml 
   /// </summary> 
	
   public partial class App : Application { 
      public static string[] Args;
		
      void app_Startup(object sender, StartupEventArgs e) { 
         // If no command line arguments were provided, don't process them 
         if (e.Args.Length == 0) return;
			
         if (e.Args.Length > 0) { 
            Args = e.Args; 
         } 
      } 
   } 
}
  • これで、MainWindowクラスで、プログラムはtxtファイルを開き、すべてのテキストをテキストボックスに書き込みます。

  • エラーが見つかった場合、プログラムはテキストボックスにエラーメッセージを表示します。

using System; 
using System.IO; 
using System.Windows;  

namespace WPFCommandLine { 

   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
         String[] args = App.Args;
			
         try {
            // Open the text file using a stream reader. 
            using (StreamReader sr = new StreamReader(args[0])) { 
               // Read the stream to a string, and write  
               // the string to the text box 
               String line = sr.ReadToEnd(); 
               textBox.AppendText(line.ToString()); 
               textBox.AppendText("\n"); 
            } 
         } 
         catch (Exception e) { 
            textBox.AppendText("The file could not be read:"); 
            textBox.AppendText("\n"); 
            textBox.AppendText(e.Message); 
         } 
      } 
   } 
}
  • 上記のコードをコンパイルして実行すると、このプログラムにはコマンドライン引数が必要なため、テキストボックスのある空白のウィンドウが生成されます。そのため、Visual Studioは、コマンドラインパラメーターを使用してアプリケーションを実行する簡単な方法を提供します。

  • ソリューションエクスプローラーでWPFプロジェクトを右クリックし、プロパティを選択すると、次のウィンドウが表示されます。

  • [デバッグ]オプションを選択し、コマンドライン引数にファイルパスを書き込みます。

  • Test.txtを使用してtxtファイルを作成し、そのファイルにテキストを書き込んで、任意の場所に保存します。この場合、txtファイルは「D:\」ハードドライブ。

  • プロジェクトに変更を保存し、今すぐアプリケーションをコンパイルして実行します。プログラムがText.txtファイルから読み取るTextBoxにテキストが表示されます。

それでは、マシンのファイル名をから変更してみましょう。 Test.txtTest1.txt プログラムを再度実行すると、テキストボックスにそのエラーメッセージが表示されます。

上記のコードを実行し、すべての手順に従ってアプリケーションを正常に実行することをお勧めします。

データバインディングは、Windowsランタイムアプリがデータを表示および操作するためのシンプルで簡単な方法を提供するWPFアプリケーションのメカニズムです。このメカニズムでは、データの管理はデータの方法から完全に分離されています。

データバインディングにより、UI要素とユーザーインターフェイス上のデータオブジェクト間のデータフローが可能になります。バインディングが確立され、データまたはビジネスモデルが変更されると、更新がUI要素に自動的に反映されます。その逆も同様です。標準のデータソースではなく、ページ上の別の要素にバインドすることもできます。

データバインディングには2つのタイプがあります- one-way data binding そして two-way data binding

一方向のデータバインディング

一方向バインディングでは、データはソース(データを保持するオブジェクト)からターゲット(データを表示するオブジェクト)にバインドされます。

  • 一方向のデータバインディングを詳細に理解するために、簡単な例を見てみましょう。まず、次の名前で新しいWPFプロジェクトを作成しますWPFDataBinding

  • 次のXAMLコードは、2つのラベル、2つのテキストボックス、および1つのボタンを作成し、いくつかのプロパティでそれらを初期化します。

<Window x:Class = "WPFDataBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFDataBinding" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
	
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "*" /> 
      </Grid.RowDefinitions> 
		
      <Grid.ColumnDefinitions> 
         <ColumnDefinition Width = "Auto" /> 
         <ColumnDefinition Width = "200" /> 
      </Grid.ColumnDefinitions>
		
      <Label Name = "nameLabel" Margin = "2">_Name:</Label> 
		
      <TextBox Name = "nameText" Grid.Column = "1" Margin = "2" 
         Text = "{Binding Name, Mode = OneWay}"/>  
			
      <Label Name = "ageLabel" Margin = "2" Grid.Row = "1">_Age:</Label> 
		
      <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "2" 
         Text = "{Binding Age, Mode = OneWay}"/>  
			
      <StackPanel Grid.Row = "2" Grid.ColumnSpan = "2"> 
         <Button Content = "_Show..." Click="Button_Click" /> 
      </StackPanel> 
		
   </Grid> 
</Window>
  • 両方のテキストボックスのテキストプロパティは、以下に示すPersonクラスのクラス変数である「Name」と「Age」にバインドされます。

  • Personクラスには、2つの変数しかありません Name そして Age、およびそのオブジェクトはで初期化されます MainWindow クラス。

  • XAMLコードでは、プロパティNameとAgeにバインドしていますが、そのプロパティが属するオブジェクトを選択していません。

  • より簡単な方法は、オブジェクトをに割り当てることです DataContext そのプロパティは、次のC#コードでバインドしています MainWindowconstructor

using System.Windows;  
namespace WPFDataBinding { 

   public partial class MainWindow : Window {
	
      Person person = new Person { Name = "Salman", Age = 26 };
		
      public MainWindow() { 
         InitializeComponent(); 
         this.DataContext = person; 
      } 
		
      private void Button_Click(object sender, RoutedEventArgs e) { 
         string message = person.Name + " is " + person.Age; 
         MessageBox.Show(message); 
      } 
   } 
	
   public class Person { 
	
      private string nameValue;
		
      public string Name { 
         get { return nameValue; } 
         set { nameValue = value; } 
      } 
		
      private double ageValue; 
		
      public double Age { 
         get { return ageValue; } 
				
         set { 
            if (value != ageValue) { 
               ageValue = value; 
            } 
         } 
      }
		
   } 
}
  • このアプリケーションを実行してみましょう。メインウィンドウで、そのPersonオブジェクトのNameとAgeに正常にバインドされていることがすぐにわかります。

を押すと Show ボタンをクリックすると、メッセージボックスに名前と年齢が表示されます。

ダイアログボックスで名前と年齢を変更しましょう。

ここで[表示]ボタンをクリックすると、同じメッセージが再び表示されます。

これは、XAMLコードでデータバインディングモードが一方向に設定されているためです。更新されたデータを表示するには、双方向のデータバインディングを理解する必要があります。

双方向データバインディング

双方向バインディングでは、ユーザーはユーザーインターフェイスを介してデータを変更し、そのデータをソースで更新することができます。ユーザーがビューを見ているときにソースが変更された場合は、ビューを更新する必要があります。

同じ例を見てみましょうが、ここでは、XAMLコードでバインディングモードを一方向から双方向に変更します。

<Window x:Class = "WPFDataBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFDataBinding" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
	
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "*" /> 
      </Grid.RowDefinitions> 
		
      <Grid.ColumnDefinitions> 
         <ColumnDefinition Width = "Auto" /> 
         <ColumnDefinition Width = "200" /> 
      </Grid.ColumnDefinitions> 
		
      <Label Name = "nameLabel" Margin = "2">_Name:</Label> 
      <TextBox Name = "nameText" Grid.Column = "1" Margin = "2" 
         Text = "{Binding Name, Mode = TwoWay}"/>  
      <Label Name = "ageLabel" Margin = "2" Grid.Row = "1">_Age:</Label> 
      <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "2" 
         Text = "{Binding Age, Mode = TwoWay}"/> 
			
      <StackPanel Grid.Row = "2" Grid.ColumnSpan = "2"> 
         <Button Content = "_Show..." Click = "Button_Click" /> 
      </StackPanel>
		
   </Grid>
	
</Window>

このアプリケーションをもう一度実行してみましょう。

同じ出力を生成します-

名前と年齢の値を変更しましょう-

ここで[表示]ボタンをクリックすると、更新されたメッセージが表示されます。

概念をよりよく理解するために、両方のケースで上記のコードを実行することをお勧めします。

リソースは通常、複数回使用することが予想されるオブジェクトに関連する定義です。これは、コントロール用または現在のウィンドウ用にローカルに、またはアプリケーション全体用にグローバルにデータを保存する機能です。

オブジェクトをリソースとして定義すると、別の場所からオブジェクトにアクセスできるようになります。これは、オブジェクトを再利用できることを意味します。リソースはリソースディクショナリで定義され、任意のオブジェクトをリソースとして定義して、効果的に共有可能なアセットにすることができます。一意のキーがXAMLリソースに指定され、そのキーを使用して、StaticResourceマークアップ拡張機能を使用して参照できます。

リソースには2つのタイプがあります-

  • StaticResource
  • DynamicResource

StaticResourceは1回限りのルックアップですが、DynamicResourceはデータバインディングのように機能します。プロパティが特定のリソースキーに関連付けられていることを記憶しています。そのキーに関連付けられているオブジェクトが変更されると、動的リソースはターゲットプロパティを更新します。

SolidColorBrushリソースの簡単なアプリケーションを次に示します。

  • 名前の付いた新しいWPFプロジェクトを作成しましょう WPFResouces

  • 次のXAMLコードに示すように、2つの長方形をドラッグし、それらのプロパティを設定します。

<Window x:Class = "WPFResources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFResources" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Window.Resources> 
      <SolidColorBrush x:Key = "brushResource" Color = "Blue" /> 
   </Window.Resources> 
	
   <StackPanel> 
      <Rectangle Height = "50" Margin = "20" Fill = "{StaticResource brushResource}" /> 
      <Rectangle Height = "50" Margin = "20" Fill = "{DynamicResource brushResource}" /> 
      <Button x:Name = "changeResourceButton"
         Content = "_Change Resource" Click = "changeResourceButton_Click" /> 
   </StackPanel> 
	
</Window>
  • 上記のXAMLコードでは、一方の長方形にStaticResourceがあり、もう一方の長方形にDynamicResourceがあり、brushResourceの色がBisqueであることがわかります。

  • コードをコンパイルして実行すると、次のメインウィンドウが生成されます。

[リソースの変更]ボタンをクリックすると、DynamicResourceのある長方形の色が赤に変わることがわかります。

リソーススコープ

リソースはで定義されています resource dictionaries、しかし、リソース辞書を定義できる場所はたくさんあります。上記の例では、リソースディクショナリはウィンドウ/ページレベルで定義されています。どの辞書でリソースが定義されているかによって、そのリソースの範囲がすぐに制限されます。したがって、スコープ、つまりリソー​​スを使用できる場所は、リソースを定義した場所によって異なります。

  • グリッドのリソースディクショナリでリソースを定義すると、そのグリッドとその子要素からのみアクセスできます。

  • ウィンドウ/ページで定義すると、そのウィンドウ/ページのすべての要素からアクセスできます。

  • アプリのルートは、App.xamlリソース辞書にあります。これはアプリケーションのルートであるため、ここで定義されているリソースはアプリケーション全体にスコープされています。

リソースの範囲に関する限り、ほとんどの場合、アプリケーションレベル、ページレベル、およびGrid、StackPanelなどの特定の要素レベルです。

上記のアプリケーションには、ウィンドウ/ページレベルのリソースがあります。

リソース辞書

XAMLアプリのリソースディクショナリは、リソースディクショナリが別々のファイルに保持されていることを意味します。これは、ほとんどすべてのXAMLアプリで使用されています。個別のファイルでリソースを定義すると、次の利点があります。

  • リソースディクショナリでのリソースの定義とUI関連コードの分離。

  • App.xamlなどの個別のファイルですべてのリソースを定義すると、アプリ全体でそれらを利用できるようになります。

では、別のファイルのリソースディクショナリでリソースをどのように定義するのでしょうか。さて、それは非常に簡単です。以下に示す手順に従って、VisualStudioから新しいリソース辞書を追加するだけです。

  • ソリューションで、新しいフォルダーを追加して名前を付けます ResourceDictionaries

  • このフォルダを右クリックし、[サブメニュー項目の追加]から[リソースディクショナリ]を選択して名前を付けます DictionaryWithBrush.xaml

同じ例を見てみましょうが、ここでは、アプリレベルでリソースディクショナリを定義します。MainWindow.xamlのXAMLコードは次のとおりです-

<Window x:Class = "WPFResources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFResources" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <StackPanel> 
      <Rectangle Height = "50" Margin = "20" Fill = "{StaticResource brushResource}" /> 
      <Rectangle Height = "50" Margin = "20" Fill = "{DynamicResource brushResource}" /> 
      <Button x:Name = "changeResourceButton"
         Content = "_Change Resource" Click = "changeResourceButton_Click" /> 
   </StackPanel> 
	
</Window>

これがDictionaryWithBrush.xamlの実装です-

<ResourceDictionary xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"> 
   <SolidColorBrush x:Key = "brushResource" Color = "Blue" /> 
</ResourceDictionary>

これがapp.xamlの実装です-

<Application x:Class="WPFResources.App" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   StartupUri = "MainWindow.xaml"> 
	
   <Application.Resources> 
      <ResourceDictionary Source = " XAMLResources\ResourceDictionaries\DictionaryWithBrush.xaml"/> 
   </Application.Resources> 
	
</Application>

上記のコードをコンパイルして実行すると、次の出力が生成されます。

[リソースの変更]ボタンをクリックすると、長方形の色が赤に変わります。

上記のコードを実行して、さらにいくつかのリソース(背景色など)を試すことをお勧めします。

テンプレートは、コントロールの全体的な外観と視覚的な外観を記述します。コントロールごとに、コントロールに外観を与えるデフォルトのテンプレートが関連付けられています。WPFアプリケーションでは、コントロールの視覚的な動作と視覚的な外観をカスタマイズするときに、独自のテンプレートを簡単に作成できます。

ロジックとテンプレート間の接続は、データバインディングによって実現できます。の主な違いstyles そして templates 以下にリストされています-

  • スタイルは、そのコントロールのデフォルトのプロパティを使用してのみ、コントロールの外観を変更できます。

  • テンプレートを使用すると、スタイルよりもコントロールの多くの部分にアクセスできます。コントロールの既存の動作と新しい動作の両方を指定することもできます。

最も一般的に使用されるテンプレートには2つのタイプがあります-

  • コントロールテンプレート
  • データテンプレート

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

コントロールテンプレートは、コントロールの外観を定義します。すべてのUI要素には、動作だけでなく何らかの外観もあります。たとえば、Buttonには外観と動作があります。クリックイベントまたはマウスホバーイベントは、クリックアンドホバーに応答して発生する動作であり、コントロールテンプレートによって変更できるボタンのデフォルトの外観もあります。

簡単な例を見てみましょう。2つのボタン(1つはテンプレート付き、もう1つはデフォルトボタン)を作成し、いくつかのプロパティで初期化します。

<Window x:Class = "TemplateDemo.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Window.Resources> 
      <ControlTemplate x:Key = "ButtonTemplate" TargetType = "Button">
		
         <Grid> 
            <Ellipse x:Name = "ButtonEllipse" Height = "100" Width = "150" > 
               <Ellipse.Fill> 
                  <LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4"> 
                     <GradientStop Offset = "0" Color = "Red" /> 
                     <GradientStop Offset = "1" Color = "Orange" /> 
                  </LinearGradientBrush> 
               </Ellipse.Fill> 
            </Ellipse> 
				
            <ContentPresenter Content = "{TemplateBinding Content}" 
               HorizontalAlignment = "Center" VerticalAlignment = "Center" /> 
         </Grid> 
			
         <ControlTemplate.Triggers> 
			
            <Trigger Property = "IsMouseOver" Value = "True"> 
               <Setter TargetName = "ButtonEllipse" Property = "Fill" > 
                  <Setter.Value> 
                     <LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4"> 
                        <GradientStop Offset = "0" Color = "YellowGreen" /> 
                        <GradientStop Offset = "1" Color = "Gold" /> 
                     </LinearGradientBrush> 
                  </Setter.Value> 
               </Setter> 
            </Trigger> 
				
            <Trigger Property = "IsPressed" Value = "True"> 
               <Setter Property = "RenderTransform"> 
                  <Setter.Value> 
                     <ScaleTransform ScaleX = "0.8" ScaleY = "0.8" 
                        CenterX = "0" CenterY = "0"  /> 
                  </Setter.Value> 
               </Setter> 
               <Setter Property = "RenderTransformOrigin" Value = "0.5,0.5" /> 
            </Trigger> 
				
         </ControlTemplate.Triggers> 
			
      </ControlTemplate> 
   </Window.Resources> 
	
   <StackPanel> 
      <Button Content = "Round Button!"
         Template = "{StaticResource ButtonTemplate}" 
         Width = "150" Margin = "50" /> 
      <Button Content = "Default Button!" Height = "40" 
         Width = "150" Margin = "5" />
   </StackPanel> 
	
</Window>

上記のコードをコンパイルして実行すると、次のメインウィンドウが表示されます。

カスタムテンプレートを使用してボタンの上にマウスを移動すると、次のように色が変わります。

データテンプレート

データテンプレートは、データのコレクションの外観と構造を定義および指定します。これにより、任意のUI要素でのデータの表示をフォーマットおよび定義する柔軟性が提供されます。これは主に、ComboBox、ListBoxなどのデータ関連のアイテムコントロールで使用されます。

  • データテンプレートの概念を理解するために簡単な例を見てみましょう。名前で新しいWPFプロジェクトを作成しますWPFDataTemplates

  • 次のXAMLコードでは、ラベルとテキストボックスを保持するためのリソースとしてデータテンプレートを作成します。データを表示するためのボタンとリストボックスもあります。

<Window x:Class = "WPFDataTemplates.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFDataTemplates" 
   xmlns:loc = "clr-namespace:WPFDataTemplates" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Window.Resources> 
      <DataTemplate DataType = "{x:Type loc:Person}"> 
		
         <Grid> 
            <Grid.RowDefinitions> 
               <RowDefinition Height = "Auto" /> 
               <RowDefinition Height = "Auto" /> 
            </Grid.RowDefinitions> 
				
            <Grid.ColumnDefinitions> 
               <ColumnDefinition Width = "Auto" /> 
               <ColumnDefinition Width = "200" /> 
            </Grid.ColumnDefinitions>
				
            <Label Name = "nameLabel" Margin = "10"/> 
            <TextBox Name = "nameText" Grid.Column = "1" Margin = "10" 
               Text = "{Binding Name}"/>  
            <Label Name = "ageLabel" Margin = "10" Grid.Row = "1"/> 
            <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "10" 
               Text = "{Binding Age}"/> 
         </Grid> 
			
      </DataTemplate> 
   </Window.Resources> 
	
   <Grid> 
      <Grid.RowDefinitions> 
         <RowDefinition Height = "Auto" /> 
         <RowDefinition Height = "*" /> 
      </Grid.RowDefinitions> 
		
      <ListBox ItemsSource = "{Binding}" />  
      <StackPanel Grid.Row = "1" > 
         <Button Content = "_Show..." Click = "Button_Click" Width = "80" HorizontalAlignment = "Left" Margin = "10"/> 
      </StackPanel> 
		
   </Grid> 
	
</Window>

ここは implementation in C# PersonオブジェクトのリストがDataContext、Personクラスの実装、およびボタンクリックイベントに割り当てられます。

using System.Collections.Generic; 
using System.Windows;
  
namespace WPFDataTemplates { 

   public partial class MainWindow : Window { 
	
      Person src = new Person { Name = "Ali", Age = 27 }; 
      List<Person> people = new List<Person>(); 
		
      public MainWindow() { 
         InitializeComponent(); 
         people.Add(src); 
         people.Add(new Person { Name = "Mike", Age = 62 }); 
         people.Add(new Person { Name = "Brian", Age = 12 });  
         this.DataContext = people; 
      } 
		
      private void Button_Click(object sender, RoutedEventArgs e) { 
         string message = src.Name + " is " + src.Age; 
         MessageBox.Show(message); 
      } 
   } 
	
   public class Person { 
      private string nameValue; 
		
      public string Name { 
         get { return nameValue; } 
         set { nameValue = value; } 
      }  
		
      private double ageValue; 
		
      public double Age { 
         get { return ageValue; } 
         set { 
            if (value != ageValue) { 
            ageValue = value; 
            } 
         } 
      } 
   } 
	
}

上記のコードをコンパイルして実行すると、次のウィンドウが表示されます。これには1つのリストが含まれ、リストボックス内の各リストボックス項目には、ラベルボックスとテキストボックスに表示されるPersonクラスオブジェクトデータが含まれています。

.NET Frameworkは、アプリケーションの外観をパーソナライズおよびカスタマイズするためのいくつかの戦略を提供します。スタイルは、オブジェクトのいくつかのプロパティを設定し、これらの特定の設定を複数のオブジェクトで再利用して一貫した外観にする柔軟性を提供します。

  • スタイルでは、高さ、幅、フォントサイズなど、オブジェクトの既存のプロパティのみを設定できます。

  • コントロールのデフォルトの動作のみを指定できます。

  • 複数のプロパティを1つのスタイルに追加できます。

スタイルは、一連のコントロールに均一な外観または外観を与えるために使用されます。暗黙的なスタイルは、特定のタイプのすべてのコントロールに外観を適用し、アプリケーションを簡素化するために使用されます。3つのボタンを想像してみてください。すべて同じ、同じ幅と高さ、同じフォントサイズ、同じ前景色などに見える必要があります。これらのプロパティはすべてボタン要素自体に設定できますが、それでもすべてのボタンで問題ありません。次の図を見てください。

しかし、実際のアプリケーションでは、通常、まったく同じように見える必要があるこれらの多くがあります。もちろん、ボタンだけでなく、通常、テキストブロック、テキストボックス、コンボボックスなどをアプリケーション全体で同じように表示する必要があります。確かに、これを達成するためのより良い方法があるはずであり、それはとして知られていますstyling。スタイルは、プロパティ値のセットを複数の要素に適用するための便利な方法と考えることができます。次の図を見てください。

この概念を理解するために簡単な例を見てみましょう。新しいWPFプロジェクトを作成することから始めます。

  • ツールボックスからデザインウィンドウに3つのボタンをドラッグします。

  • 次のXAMLコードは、3つのボタンを作成し、いくつかのプロパティでそれらを初期化します。

<Window x:Class = "WPFStyle.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace: WPFStyle" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <Button Content = "Button1" Height = "30" Width = "80" 
         Foreground = "Blue" FontSize = "12" Margin = "10"/> 
      <Button Content = "Button2" Height = "30" Width = "80" 
         Foreground = "Blue" FontSize = "12" Margin = "10"/> 
      <Button Content = "Button3" Height = "30" Width = "80" 
         Foreground = "Blue" FontSize = "12" Margin = "10"/> 
   </StackPanel> 
	
</Window>

上記のコードを見ると、すべてのボタンの高さ、幅、前景色、フォントサイズ、マージンのプロパティが同じであることがわかります。上記のコードをコンパイルして実行すると、次のウィンドウが表示されます。

同じ例を見てみましょうが、今回は使用します style

<Window x:Class = "XAMLStyle.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
   xmlns:local = "clr-namespace:XAMLStyle" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
	
   <Window.Resources> 
      <Style x:Key = "myButtonStyle" TargetType = "Button"> 
         <Setter Property = "Height" Value = "30" /> 
         <Setter Property = "Width" Value = "80" /> 
         <Setter Property = "Foreground" Value = "Blue" /> 
         <Setter Property = "FontSize" Value = "12" /> 
         <Setter Property = "Margin" Value = "10" /> 
      </Style> 
   </Window.Resources> 
	
   <StackPanel> 
      <Button Content = "Button1" Style = "{StaticResource myButtonStyle}" /> 
      <Button Content = "Button2" Style = "{StaticResource myButtonStyle}" /> 
      <Button Content = "Button3" Style="{StaticResource myButtonStyle}" /> 
   </StackPanel> 
	
</Window>

スタイルはリソースディクショナリで定義され、各スタイルには一意のキー識別子とターゲットタイプがあります。<style>内では、スタイルに含まれるプロパティごとに複数のセッタータグが定義されていることがわかります。

上記の例では、各ボタンのすべての共通プロパティがスタイルで定義され、StaticResourceマークアップ拡張機能を介してstyleプロパティを設定することにより、スタイルが一意のキーで各ボタンに割り当てられます。

上記のコードをコンパイルして実行すると、次のウィンドウが表示されます(同じ出力)。

このようにすることの利点はすぐに明らかです。スコープ内のどこでもそのスタイルを再利用できます。変更する必要がある場合は、各要素ではなく、スタイル定義で1回変更するだけです。

どのレベルでスタイルが定義されるかによって、そのスタイルの範囲が即座に制限されます。したがって、スコープ、つまりスタイルを使用できる場所は、定義した場所によって異なります。スタイルは次のレベルで定義できます-

シニア番号 レベルと説明
1 コントロールレベル

コントロールレベルでのスタイルの定義は、その特定のコントロールにのみ適用できます。以下に示すのは、ボタンとTextBlockが独自のスタイルを持つコントロールレベルの例です。

2 レイアウトレベル

任意のレイアウトレベルでスタイルを定義すると、そのレイアウトとその子要素からのみアクセスできるようになります。

3 ウィンドウレベル

ウィンドウレベルでスタイルを定義すると、そのウィンドウのすべての要素からスタイルにアクセスできるようになります。

4 アプリケーションレベル

アプリレベルでスタイルを定義すると、アプリケーション全体でスタイルにアクセスできるようになります。同じ例を見てみましょうが、ここでは、アプリケーション全体でアクセスできるように、スタイルをapp.xamlファイルに配置します。

トリガーを使用すると、基本的に、プロパティ値を変更したり、プロパティの値に基づいてアクションを実行したりできます。そのため、新しいコントロールを作成しなくても、コントロールの外観や動作を動的に変更できます。

トリガーは、特定の条件が満たされたときに、特定のプロパティの値を変更するために使用されます。トリガーは通常、その特定のコントロールに適用されるスタイルまたはドキュメントのルートで定義されます。トリガーには3つのタイプがあります-

  • プロパティトリガー
  • データトリガー
  • イベントトリガー

プロパティトリガー

プロパティトリガーでは、あるプロパティで変更が発生すると、別のプロパティで即時またはアニメーションの変更が発生します。たとえば、プロパティトリガーを使用して、マウスをボタンの上に置いたときのボタンの外観を変更できます。

次のサンプルコードは、マウスをボタンの上に置いたときにボタンの前景色を変更する方法を示しています。

<Window x:Class = "WPFPropertyTriggers.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Window.Resources> 
      <Style x:Key = "TriggerStyle" TargetType = "Button"> 
         <Setter Property = "Foreground" Value = "Blue" /> 
         <Style.Triggers> 
            <Trigger Property = "IsMouseOver" Value = "True"> 
               <Setter Property = "Foreground" Value = "Green" /> 
            </Trigger> 
         </Style.Triggers> 
      </Style> 
   </Window.Resources> 
	
   <Grid> 
      <Button Width = "100" Height = "70"
         Style = "{StaticResource TriggerStyle}" Content = "Trigger"/> 
   </Grid> 
	
</Window>

上記のコードをコンパイルして実行すると、次のウィンドウが表示されます-

マウスをボタンの上に置くと、前景色が緑色に変わります。

データトリガー

バインドされたデータがいくつかの条件を満たすと、データトリガーはいくつかのアクションを実行します。チェックボックスとテキストブロックがいくつかのプロパティで作成されている次のXAMLコードを見てみましょう。チェックボックスをオンにすると、前景色が赤に変わります。

<Window x:Class = "WPFDataTrigger.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "Data Trigger" Height = "350" Width = "604">
	
   <StackPanel HorizontalAlignment = "Center"> 
      <CheckBox x:Name = "redColorCheckBox" 
         Content = "Set red as foreground color" Margin = "20"/> 
			
      <TextBlock Name = "txtblock" VerticalAlignment = "Center" 
         Text = "Event Trigger" FontSize = "24" Margin = "20"> 
         <TextBlock.Style> 
            <Style> 
               <Style.Triggers> 
                  <DataTrigger Binding = "{Binding ElementName = redColorCheckBox, Path = IsChecked}" 
                     Value = "true"> 
                     <Setter Property = "TextBlock.Foreground" Value = "Red"/> 
                     <Setter Property = "TextBlock.Cursor" Value = "Hand" /> 
                  </DataTrigger> 
               </Style.Triggers> 
            </Style> 
         </TextBlock.Style> 
      </TextBlock> 
		
   </StackPanel> 
	
</Window>

上記のコードをコンパイルして実行すると、次の出力が生成されます。

チェックボックスをオンにすると、テキストブロックの前景色が赤に変わります。

イベントトリガー

イベントトリガーは、特定のイベントが発生したときにいくつかのアクションを実行します。これは通常、DoubleAnumatio、ColorAnimationなどのコントロールでアニメーションを実行するために使用されます。次の例では、単純なボタンを作成します。クリックイベントが発生すると、ボタンの幅と高さが拡張されます。

<Window x:Class = "WPFEventTrigger.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button Content = "Click Me" Width = "60" Height = "30">
		
         <Button.Triggers> 
            <EventTrigger RoutedEvent = "Button.Click"> 
               <EventTrigger.Actions> 
                  <BeginStoryboard> 
                     <Storyboard> 
							
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = 
                           "Width" Duration = "0:0:4"> 
                           <LinearDoubleKeyFrame Value = "60" KeyTime = "0:0:0"/> 
                           <LinearDoubleKeyFrame Value = "120" KeyTime = "0:0:1"/> 
                           <LinearDoubleKeyFrame Value = "200" KeyTime = "0:0:2"/> 
                           <LinearDoubleKeyFrame Value = "300" KeyTime = "0:0:3"/> 
                        </DoubleAnimationUsingKeyFrames>
								
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "Height" 
                           Duration = "0:0:4"> 
                           <LinearDoubleKeyFrame Value = "30" KeyTime = "0:0:0"/> 
                           <LinearDoubleKeyFrame Value = "40" KeyTime = "0:0:1"/> 
                           <LinearDoubleKeyFrame Value = "80" KeyTime = "0:0:2"/> 
                           <LinearDoubleKeyFrame Value = "150" KeyTime = "0:0:3"/> 
                        </DoubleAnimationUsingKeyFrames>
								
                     </Storyboard> 
                  </BeginStoryboard> 
               </EventTrigger.Actions> 
            </EventTrigger> 
         </Button.Triggers> 
			
      </Button> 
   </Grid> 
	
</Window>

上記のコードをコンパイルして実行すると、次のウィンドウが表示されます-

ボタンをクリックすると、両方の次元で拡大し始めることがわかります。

上記の例をコンパイルして実行し、他のプロパティにもトリガーを適用することをお勧めします。

これは、コードのバグや欠陥を特定して修正する体系的なメカニズムであり、期待どおりに動作しません。サブシステムが緊密に結合されている複雑なアプリケーションのデバッグは、あるサブシステムのバグを修正すると別のサブシステムにバグが発生する可能性があるため、それほど簡単ではありません。

C#でのデバッグ

WPFアプリケーションでは、プログラマーはC#やXAMLなどの2つの言語を扱います。C#やC / C ++などの手続き型言語でのデバッグに精通していて、ブレークポイントの使用法も知っている場合は、アプリケーションのC#部分を簡単にデバッグできます。

C#コードをデバッグする方法を示す簡単な例を見てみましょう。名前で新しいWPFプロジェクトを作成しますWPFDebuggingDemo。ツールボックスから4つのラベル、3つのテキストボックス、および1つのボタンをドラッグします。次のXAMLコードを見てください。

<Window x:Class = "WPFDebuggingDemo.Window1" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "Window1" Height = "400" Width = "604"> 
	
   <Grid> 
      <TextBox Height = "23" Margin = "0,44,169,0" Name = "textBox1"  
         VerticalAlignment = "Top" HorizontalAlignment = "Right" Width = "120" /> 
			
      <TextBox Height = "23" Margin = "0,99,169,0" Name = "textBox2"  
         VerticalAlignment = "Top" HorizontalAlignment = "Right" Width = "120" /> 
			
      <TextBox HorizontalAlignment = "Right" Margin = "0,153,169,0"  
         Name = "textBox3" Width = "120" Height = "23" VerticalAlignment = "Top" /> 
			
      <Label Height = "28" Margin = "117,42,0,0" Name = "label1"  
         VerticalAlignment = "Top" HorizontalAlignment = "Left" Width = "120">
         Item 1</Label> 
			
      <Label Height = "28" HorizontalAlignment = "Left"  
         Margin = "117,99,0,0" Name = "label2" VerticalAlignment = "Top" Width = "120">
         Item 2</Label> 
			
      <Label HorizontalAlignment = "Left" Margin = "117,153,0,181"  
         Name = "label3" Width = "120">Item 3</Label>
			
      <Button Height = "23" HorizontalAlignment = "Right" Margin = "0,0,214,127"
         Name = "button1" VerticalAlignment = "Bottom" Width = "75"  
         Click = "button1_Click">Total</Button> 
			
      <Label Height = "28" HorizontalAlignment = "Right"  
         Margin = "0,0,169,66" Name = "label4" VerticalAlignment = "Bottom" Width = "120"/> 
			
   </Grid> 
	
</Window>

以下に示すのは、ボタンクリックイベントが実装されているC#コードです。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text;
 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes;  

namespace WPFDebuggingDemo { 
   /// <summary> 
      /// Interaction logic for Window1.xaml 
   /// </summary> 
	
   public partial class Window1 : Window { 
	
      public Window1() {
         InitializeComponent();
      }
		
      private void button1_Click(object sender, RoutedEventArgs e) {
		
         if (textBox1.Text.Length > 0 && textBox2.Text.Length > 0 && textBox2.Text.Length > 0) {
            double total = Convert.ToDouble(textBox1.Text) + 
            Convert.ToDouble(textBox2.Text) + Convert.ToDouble(textBox3.Text); 
            label4.Content = total.ToString(); 
         } 
         else { 
            MessageBox.Show("Enter the value in all field.");
         } 
      } 
   } 
}

上記のコードをコンパイルして実行すると、次のウィンドウが表示されます。次に、テキストボックスに値を入力し、[合計]ボタンを押します。テキストボックスに入力されたすべての値を合計した後、合計値を取得します。

実際の値以外の値を入力しようとすると、上記のアプリケーションがクラッシュします。問題(クラッシュする理由)を見つけて解決するために、ボタンクリックイベントにブレークポイントを挿入できます。

以下のように項目1に「abc」と書いてみましょう。

[合計]ボタンをクリックすると、プログラムがブレークポイントで停止することがわかります。

次に、カーソルをtextbox1.Textの方向に移動すると、プログラムが追加しようとしていることがわかります。 abc プログラムがクラッシュする理由である他の値との値。

XAMLでのデバッグ

XAMLで同じ種類のデバッグを期待している場合は、他の手続き型言語コードのデバッグのようにXAMLコードをデバッグすることはまだできないことを知って驚かれることでしょう。XAMLコードでデバッグという用語を聞いた場合、それはエラーを見つけようとすることを意味します。

  • データバインディングでは、データが画面に表示されず、理由がわかりません

  • または、問題が複雑なレイアウトに関連しています。

  • または、リストボックスやコンボボックスなどの広範なテンプレートを使用した、配置の問題や余白の色、オーバーレイなどの問題。

XAMLプログラムのデバッグは、バインディングが機能するかどうかを確認するために通常行うことです。それが機能していない場合は、何が問題なのかを確認します。残念ながら、XAMLバインディングにブレークポイントを設定することはSilverlightを除いて不可能ですが、[出力]ウィンドウを使用してデータバインディングエラーをチェックできます。次のXAMLコードを見て、データバインディングのエラーを見つけましょう。

<Window x:Class = "DataBindingOneWay.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <StackPanel Name = "Display"> 
         <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0"> 
            <TextBlock Text = "Name: " Margin = "10" Width = "100"/> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding FirstName}"/> 
         </StackPanel> 
			
         <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0"> 
            <TextBlock Text = "Title: " Margin = "10" Width = "100"/> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding Title}" /> 
         </StackPanel> 
			
      </StackPanel> 
   </Grid> 
	
</Window>

2つのテキストブロックのテキストプロパティは静的に「Name」と「Title」に設定され、他の2つのテキストブロックのテキストプロパティは「FirstName」と「Title」にバインドされますが、クラス変数は以下に示すEmployeeクラスのNameとTitleです。

目的の出力が表示されない場合にこのタイプの間違いをどこで見つけることができるかを理解するために、意図的に誤った変数名を記述しました。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;  

namespace DataBindingOneWay { 

   public class Employee { 
      public string Name { get; set; } 
      public string Title { get; set; }  
		
      public static Employee GetEmployee() { 
		
         var emp = new Employee() { 
            Name = "Ali Ahmed", Title = "Developer" 
         }; 
			
         return emp; 
      }  
   } 
}

これは、C#コードでのMainWindowクラスの実装です。

using System; 
using System.Windows; 
using System.Windows.Controls; 
 
namespace DataBindingOneWay { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml
   /// </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
         DataContext = Employee.GetEmployee(); 
      } 
   } 
}

このアプリケーションを実行してみましょう。メインウィンドウで、そのEmployeeオブジェクトのTitleに正常にバインドされたが、名前がバインドされていないことがすぐにわかります。

名前で何が起こったのかを確認するために、大量のログが生成される出力ウィンドウを調べてみましょう。

エラーを見つけるのは簡単です。エラーを検索するだけで、「BindingExpression path error: 'FirstName' property not found on'object''Employe」というエラーが見つかります。

System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName'
   property not found on 'object' ''Employee' (HashCode=11611730)'.
   BindingExpression:Path = FirstName; DataItem = 'Employee' (HashCode = 11611730);
   target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

これは、FirstNameがEmployeeクラスのメンバーではないことを明確に示しているため、アプリケーションでこのタイプの問題を修正するのに役立ちます。

FirstNameをNameに再度変更すると、目的の出力が表示されます。

XAML用のUIデバッグツール

実行時にXAMLコードを検査するために、Visual Studio2015でXAML用のUIデバッグツールが導入されました。これらのツールを使用すると、XAMLコードは、実行中のWPFアプリケーションのビジュアルツリーの形式で表示され、ツリー内のさまざまなUI要素のプロパティも表示されます。これらのツールを有効にするには、以下の手順に従ってください。

  • [ツール]メニューに移動し、[ツール]メニューから[オプション]を選択します。
  • 次のダイアログボックスが開きます。
  • 左側の[デバッグ]項目の[一般オプション]に移動します。
  • 強調表示されたオプション、つまり「XAMLのUIデバッグツールを有効にする」にチェックマークを付け、[OK]ボタンをクリックします。

次に、任意のXAMLアプリケーションを実行するか、次のXAMLコードを使用します。

<Window x:Class = "XAMLTestBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <ComboBox Name = "comboBox"  Margin = "50" Width = "100"> 
         <ComboBoxItem Content = "Green" /> 
         <ComboBoxItem  Content = "Yellow" IsSelected = "True" />
         <ComboBoxItem Content = "Orange" /> 
      </ComboBox> 
		
      <TextBox  Name = "textBox" Margin = "50" Width = "100" Height = "23"
         VerticalAlignment = "Top" Text  =
         "{Binding ElementName = comboBox, Path = SelectedItem.Content, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" 
         Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}"> 
      </TextBox> 
		
   </StackPanel> 
	
</Window>

アプリケーションを実行すると、すべての要素がツリーに表示されるライブビジュアルツリーが表示されます。

このライブビジュアルツリーは、UI要素が配置されている場所を理解するための完全なレイアウト構造を示しています。ただし、このオプションはVisual Studio2015でのみ使用できます。VisualStudioの古いオプションを使用している場合、このツールは使用できませんが、XAML Spy for VisualStudioなどのVisualStudioと統合できる別のツールがあります。 。xamlspyからダウンロードできます

WPFアプリケーションを使用すると、カスタムコントロールを作成できるため、機能が豊富でカスタマイズ可能なコントロールを非常に簡単に作成できます。カスタムコントロールは、Microsoftが提供するすべての組み込みコントロールが基準を満たしていない場合、またはサードパーティのコントロールにお金をかけたくない場合に使用されます。

この章では、カスタムコントロールを作成する方法を学習します。カスタムコントロールについて説明する前に、まずユーザーコントロールについて簡単に説明します。

ユーザーコントロール

ユーザーコントロールは、さまざまな組み込みコントロールを収集して結合し、それらを再利用可能なXAMLにパッケージ化する方法を提供します。ユーザーコントロールは、次のシナリオで使用されます-

  • コントロールが既存のコントロールで構成されている場合、つまり、複数の既存のコントロールからなる単一のコントロールを作成できます。

  • コントロールがテーマのサポートを必要としない場合。ユーザーコントロールは、複雑なカスタマイズ、コントロールテンプレート、およびスタイル設定が難しいものをサポートしていません。

  • 開発者が、ビューとイベントハンドラーの直接コードビハインドのコードビハインドモデルを使用してコントロールを作成することを好む場合。

  • アプリケーション間で制御を共有することはありません。

ユーザーコントロールの例に移動し、以下の手順に従います。

  • 新しいWPFプロジェクトを作成し、ソリューションを右クリックして、[追加]> [新しいアイテム...]を選択します。

  • 次のウィンドウが開きます。今選択User Control (WPF) MyUserControlという名前を付けます。

  • [追加]ボタンをクリックすると、2つの新しいファイル(MyUserControl.xamlとMyUserControl.cs)がソリューションに追加されることがわかります。

これは、MyUserControl.xamlファイルのいくつかのプロパティを使用してボタンとテキストボックスが作成されるXAMLコードです。

<UserControl x:Class = "WPFUserControl.MyUserControl" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"  
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"  
   mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300"> 
	
   <Grid> 
      <TextBox Height = "23"  
         HorizontalAlignment = "Left"  
         Margin = "80,49,0,0" Name = "txtBox"  
         VerticalAlignment = "Top" Width = "200" /> 
			
      <Button Content = "Click Me"  
         Height = "23" HorizontalAlignment = "Left"  
         Margin = "96,88,0,0" Name = "button"  
         VerticalAlignment = "Top" Click = "button_Click" />    
   </Grid>
	
</UserControl>

以下に示すのは、テキストボックスを更新するMyUserControl.csファイルのボタンクリックイベントのC#コードです。

using System; 
using System.Windows; 
using System.Windows.Controls; 
 
namespace WPFUserControl {
   /// <summary>
      /// Interaction logic for MyUserControl.xaml 
   /// </summary> 
	
   public partial class MyUserControl : UserControl { 
	
      public MyUserControl() { 
         InitializeComponent(); 
      }  
		
      private void button_Click(object sender, RoutedEventArgs e) { 
         txtBox.Text = "You have just clicked the button"; 
      } 
   } 
}

これは、ユーザーコントロールを追加するためのMainWindow.xamlの実装です。

<Window x:Class = "XAMLUserControl.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:control = "clr-namespace:WPFUserControl" 
   Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
      <control:MyUserControl/> 
   </Grid> 
	
</Window>

上記のコードをコンパイルして実行すると、次のウィンドウが表示されます。

[クリックしてください]ボタンをクリックすると、テキストボックス内のテキストが更新されていることがわかります。

カスタムコントロール

カスタムコントロールは、generic.xamlで通常定義される独自のスタイルとテンプレートを提供するクラスです。カスタムコントロールは、次のシナリオで使用されます-

  • コントロールが存在せず、最初から作成する必要がある場合。

  • 特定のシナリオに合わせて追加のプロパティまたは追加の機能を追加することにより、既存のコントロールに機能を拡張または追加する場合。

  • コントロールがテーマ設定とスタイリングをサポートする必要がある場合。

  • アプリケーション間で制御を共有したい場合。

カスタムコントロールがどのように機能するかを理解するために例を見てみましょう。新しいWPFプロジェクトを作成し、ソリューションを右クリックして、[追加]> [新しいアイテム...]を選択します。

次のウィンドウが開きます。今選択Custom Control (WPF) 名前を付けます MyCustomControl

[追加]ボタンをクリックすると、2つの新しいファイル(Themes / Generic.xamlとMyCustomControl.cs)がソリューションに追加されることがわかります。

Generic.xamlファイルのカスタムコントロールにスタイルが設定されているXAMLコードを次に示します。

<ResourceDictionary 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFCustomControls">  
	
   <Style TargetType = "{x:Type local:MyCustomControl}"
      BasedOn = "{StaticResource {x:Type Button}}"> 
      <Setter Property = "Background" Value = "LightSalmon" /> 
      <Setter Property = "Foreground" Value = "Blue"/> 
   </Style> 
	
</ResourceDictionary>

これは、ボタンクラスから継承されたMyCustomControlクラスのC#コードであり、コンストラクターではメタデータをオーバーライドします。

using System; 
using System.Windows; 
using System.Windows.Controls; 
 
namespace WPFCustomControls { 

   public class MyCustomControl : Button { 
	
      static MyCustomControl() { 
         DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new
            FrameworkPropertyMetadata(typeof(MyCustomControl))); 
      } 
		
   } 
}

これは、テキストブロックのテキストを更新するC#でのカスタムコントロールクリックイベントの実装です。

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace WPFCustomControls { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
      }  
		
      private void customControl_Click(object sender, RoutedEventArgs e) { 
         txtBlock.Text = "You have just click your custom control"; 
      }
		
   } 
}

これは、カスタムコントロールとTextBlockを追加するためのMainWindow.xamlでの実装です。

<Window x:Class = "WPFCustomControls.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:control = "clr-namespace:WPFCustomControls" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <control:MyCustomControl x:Name = "customControl"  
         Content = "Click Me" Width = "70" 
         Margin = "10" Click = "customControl_Click"/> 
			
      <TextBlock Name = "txtBlock"  
         Width = "250" Height = "30"/> 
   </StackPanel>
	
</Window>

上記のコードをコンパイルして実行すると、カスタマイズされたボタンであるカスタムコントロールを備えた次のウィンドウが生成されます。

カスタマイズされたボタンをクリックすると、テキストブロック内のテキストが更新されていることがわかります。

例外は、プログラムの実行中に発生したエラー状態または予期しない動作です。多くの理由で例外が発生する可能性がありますが、その一部は次のとおりです。

  • コードまたは呼び出すコード(共有ライブラリなど)の障害、

  • 利用できないオペレーティングシステムリソース、

  • 共通言語ランタイムが遭遇する予期しない条件(検証できないコードなど)

構文

例外には、プログラムのフローをある部分から別の部分に転送する機能があります。.NET Frameworkでは、例外処理には次の4つのキーワードがあります-

  • try −このブロックでは、プログラムはいくつかの例外を発生させる特定の条件を識別します。

  • catch− catchキーワードは、例外のキャッチを示します。Atry ブロックの後に1つ以上が続く catch 問題を処理したいプログラム内の場所で例外ハンドラーを使用して例外をキャッチするためのブロック。

  • finally−finallyブロックは、例外がスローされるかどうかに関係なく、特定のステートメントのセットを実行するために使用されます。たとえば、ファイルを開く場合、例外が発生するかどうかに関係なく、ファイルを閉じる必要があります。

  • throw−問題が発生すると、プログラムは例外をスローします。これは、throwキーワードを使用して行われます。

これらの4つのキーワードを使用する構文は次のとおりです。

try { 
   ///This will still trigger the exception 
} 
catch (ExceptionClassName e) { 
   // error handling code 
} 
catch (ExceptionClassName e) { 
   // error handling code
}
catch (ExceptionClassName e) { 
   // error handling code 
} 
finally { 
   // statements to be executed 
}

プログラムフローの状況に応じて、tryブロックが複数の例外を発生させる可能性がある場合は、複数のcatchステートメントが使用されます。

階層

.NET Frameworkのほとんどすべての例外クラスは、直接的または間接的にExceptionクラスから派生しています。Exceptionクラスから派生した最も重要な例外クラスは次のとおりです。

  • ApplicationException class−プログラムによって生成される例外をサポートします。開発者が例外を定義したい場合、クラスはこのクラスから派生する必要があります。

  • SystemException class−これは、事前定義されたすべてのランタイムシステム例外の基本クラスです。次の階層は、ランタイムによって提供される標準の例外を示しています。

次の表に、ランタイムによって提供される標準の例外と、派生クラスを作成する必要がある条件を示します。

例外タイプ ベースタイプ 説明
Exception オブジェクト すべての例外の基本クラス。
SystemException 例外 ランタイムで生成されたすべてのエラーの基本クラス。
IndexOutOfRangeException SystemException 配列が不適切にインデックス付けされている場合にのみ、ランタイムによってスローされます。
NullReferenceException SystemException nullオブジェクトが参照されている場合にのみ、ランタイムによってスローされます。
AccessViolationException SystemException 無効なメモリにアクセスした場合にのみ、ランタイムによってスローされます。
InvalidOperationException SystemException 無効な状態のときにメソッドによってスローされます。
ArgumentException SystemException すべての引数例外の基本クラス。
ArgumentNullException ArgumentException 引数をnullにできないメソッドによってスローされます。
ArgumentOutOfRangeException ArgumentException 引数が指定された範囲内にあることを確認するメソッドによってスローされます。
ExternalException SystemException 発生する、またはランタイム外の環境を対象とする例外の基本クラス。
SEHException ExternalException Win32構造化例外処理情報をカプセル化する例外。

概念をよりよく理解するために、簡単な例を見てみましょう。名前で新しいWPFプロジェクトを作成することから始めますWPFExceptionHandling

1つのテキストボックスをツールボックスからデザインウィンドウにドラッグします。次のXAMLコードは、テキストボックスを作成し、いくつかのプロパティで初期化します。

<Window x:Class = "WPFExceptionHandling.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFExceptionHandling"
   mc:Ignorable = "d" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid> 
      <TextBox x:Name = "textBox" HorizontalAlignment = "Left"
         Height = "241" Margin = "70,39,0,0" TextWrapping = "Wrap" 
         VerticalAlignment = "Top" Width = "453"/> 
   </Grid> 
	
</Window>

これは、C#での例外処理を使用したファイルの読み取りです。

using System; 
using System.IO; 
using System.Windows;

namespace WPFExceptionHandling { 

   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
         ReadFile(0); 
      }
		
      void ReadFile(int index) { 
         string path = @"D:\Test.txt"; 
         StreamReader file = new StreamReader(path); 
         char[] buffer = new char[80]; 
			
         try { 
            file.ReadBlock(buffer, index, buffer.Length); 
            string str = new string(buffer); 
            str.Trim(); 
            textBox.Text = str; 
         }
         catch (Exception e) {
            MessageBox.Show("Error reading from "+ path + "\nMessage = "+ e.Message);
         } 
         finally { 
            if (file != null) { 
               file.Close(); 
            } 
         } 
      } 
   } 
}

上記のコードをコンパイルして実行すると、テキストボックス内にテキストが表示される次のウィンドウが生成されます。

例外が発生した場合、または手動でスローした場合(次のコードのように)、エラーのあるメッセージボックスが表示されます。

using System; 
using System.IO; 
using System.Windows;

namespace WPFExceptionHandling {
 
   public partial class MainWindow : Window {
	
      public MainWindow() { 
         InitializeComponent(); 
         ReadFile(0); 
      } 
		
      void ReadFile(int index) { 
         string path = @"D:\Test.txt"; 
         StreamReader file = new StreamReader(path); 
         char[] buffer = new char[80]; 
			
         try { 
            file.ReadBlock(buffer, index, buffer.Length); 
            string str = new string(buffer); 
            throw new Exception(); 
            str.Trim(); 
            textBox.Text = str; 
         }
         catch (Exception e) { 
            MessageBox.Show("Error reading from "+ path + "\nMessage = "+ e.Message); 
         } 
         finally { 
            if (file != null) { 
               file.Close(); 
            } 
         } 
      } 
   } 
}

上記のコードの実行中に例外が発生すると、次のメッセージが表示されます。

上記のコードを実行して、その機能を試すことをお勧めします。

ローカリゼーションとは、アプリケーションがサポートする特定のカルチャに合わせて、アプリケーションリソースをローカライズされたバージョンに変換することです。

アプリケーションを開発し、アプリケーションが1つの言語でしか利用できない場合、顧客の数とビジネスの規模が制限されます。あなたがあなたのビジネスも増やすであろうあなたの顧客基盤を増やしたいならば、あなたの製品は世界中の聴衆に利用可能で到達可能でなければなりません。費用対効果localization あなたの製品の1つは、より多くの顧客に手を差し伸べるための最良かつ最も経済的な方法の1つです。

WPFでは、ローカライズ可能なアプリケーションは非常に簡単に作成できます。 resxローカリゼーションの最も簡単なソリューションであるファイル。それがどのように機能するかを理解するために簡単な例を見てみましょう-

  • 名前で新しいWPFプロジェクトを作成します WPFLocalization

  • ソリューションエクスプローラーでは、[プロパティ]フォルダーの下にResources.resxファイルが表示されます。

  • アクセス修飾子を内部からパブリックに変更して、XAMLファイルでアクセスできるようにします。

  • 次に、アプリケーションで使用する次の文字列の名前と値を追加します。

  • Resources.en.resxおよびResources.ru-RU.resxという名前のResources.resxファイルの2つのコピーを作成します。これらは、言語および国/地域名に固有の命名規則であり、National Language Support(NLS)APIリファレンス(https://msdn.microsoft.com/en-us/goglobal/bb896001.aspx )ページ。

  • 以下に示すように、Resources.ru-RU.resxの値をロシア語に変更します。

  • デザインウィンドウに移動して、3つのテキストボックス、3つのラベル、および3つのボタンをドラッグしてみましょう。

  • XAMLファイルで、最初に名前空間宣言を追加して、ローカライズリソースを使用しますxmlns:p = "clr-namespace:WPFLocalization.Properties"

  • 以下に示すように、すべてのコントロールのプロパティを設定します。この例では、XAMLファイルのラベル、ボタン、およびウィンドウのタイトルのコンテンツにハードコードされた文字列を使用しません。* .resxファイルで定義されている文字列を使用します。たとえば、ウィンドウのタイトルには、「Title = "{x:Static p:Resources.Title}"」のように* .resxファイルで定義されているタイトル文字列を使用します

  • これは、コントロールが作成され、さまざまなプロパティで初期化されるXAMLファイルです。

<Window x:Class = "WPFLocalization.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "clr-namespace:WPFLocalization" 
   xmlns:p = "clr-namespace:WPFLocalization.Properties"
   Title = "{x:Static p:Resources.Title}" Height = "350" Width = "604">
	
   <Grid> 
      <TextBox x:Name = "textBox" HorizontalAlignment = "Left" Height = "23" 
         Margin = "128,45,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "304"/>
			
      <Label x:Name = "label" Content = "{x:Static p:Resources.Name}"
          HorizontalAlignment = "Left" Margin = "52,45,0,0" VerticalAlignment = "Top" Width = "86"/>
			 
      <TextBox x:Name = "textBox1" HorizontalAlignment = "Left" Height = "23" 
         Margin = "128,102,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "304"/> 
			
      <Label x:Name = "label1" Content = "{x:Static p:Resources.Address}" 
         HorizontalAlignment = "Left" Margin = "52,102,0,0" VerticalAlignment = "Top" Width = "86"/>
			
      <TextBox x:Name = "textBox2" HorizontalAlignment = "Left" Height = "23" 
         Margin = "128,157,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "80"/>
			
      <Label x:Name = "label2" Content = "{x:Static p:Resources.Age}" 
         HorizontalAlignment = "Left" Margin = "52,157,0,0" VerticalAlignment = "Top" Width = "86"/>
			
      <Button x:Name = "button" Content = "{x:Static p:Resources.OK_Button}" 
         HorizontalAlignment = "Left" Margin = "163,241,0,0" VerticalAlignment = "Top" Width = "75"/> 
			
      <Button x:Name = "button1" Content = "{x:Static p:Resources.Cancel_Button}" 
         HorizontalAlignment = "Left" Margin = "282,241,0,0" VerticalAlignment = "Top" Width = "75"/>
			
      <Button x:Name = "button2" Content = "{x:Static p:Resources.Help_Button}" 
         HorizontalAlignment = "Left" Margin = "392,241,0,0" VerticalAlignment = "Top" Width = "75"/> 
   </Grid> 
	
 </Window>
  • 上記のコードをコンパイルして実行すると、さまざまなコントロールを含む次のウィンドウが表示されます。

  • デフォルトでは、プログラムはデフォルトのResources.resxを使用します。Resources.ru-RU.resxファイルで定義されているロシア語のテキストを表示する場合は、以下に示すように、プログラムがApp.xamlファイルで起動するときにカルチャを明示的に設定する必要があります。

using System.Windows;

namespace WPFLocalization {
   /// <summary> 
      /// Interaction logic for App.xaml 
   /// </summary> 
	
   public partial class App : Application {
	
      App() { 
         System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("ru-RU");
         //System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en"); 
      } 
   } 
}

アプリケーションを実行すると、すべてのテキストがロシア語で表示されます。

上記のコードを実行し、他のカルチャ用のresxファイルも作成することをお勧めします。

WPFでは、相互作用は、ビューがそのビューにあるコントロールとどのように相互作用するかを示します。最も一般的に知られている相互作用には2つのタイプがあります-

  • Behaviors
  • ドラッグアンドドロップ

行動

動作は、一部の機能を再利用可能なコンポーネントにカプセル化できるExpression Blend3で導入されました。さらに動作を追加するには、これらのコンポーネントをコントロールにアタッチします。動作により、複雑なユーザーインタラクションを簡単に設計するための柔軟性が高まります。

ControlStoryBoardActionビヘイビアがコントロールにアタッチされている簡単な例を見てみましょう。

  • WPFBehaviorという名前で新しいWPFプロジェクトを作成します。

  • 次のXAMLコードは、楕円と、楕円の動きを制御する2つのボタンを作成します。

<Window 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFBehaviors" 
   xmlns:i = "http://schemas.microsoft.com/expression/2010/interactivity" 
   xmlns:ei = "http://schemas.microsoft.com/expression/2010/interactions" 
   x:Class = "WPFBehaviors.MainWindow" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
	
   <Window.Resources> 
      <Storyboard x:Key = "Storyboard1" RepeatBehavior = "Forever" AutoReverse = "True"> 
		
         <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty =
            "(UIElement.RenderTransform).(TransformGroup.Children )[3].(TranslateTransform.X)"
            Storyboard.TargetName = "ellipse"> 
            <EasingDoubleKeyFrame KeyTime = "0:0:1" Value = "301.524"/> 
            <EasingDoubleKeyFrame KeyTime = "0:0:2" Value = "2.909"/> 
         </DoubleAnimationUsingKeyFrames>
			
         <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = 
            "(UIElement.RenderTransform).(TransformGroup.Children )[3].(TranslateTransform.Y)"
            Storyboard.TargetName = "ellipse"> 
            <EasingDoubleKeyFrame KeyTime = "0:0:1" Value = "-0.485"/> 
            <EasingDoubleKeyFrame KeyTime = "0:0:2" Value = "0"/> 
         </DoubleAnimationUsingKeyFrames> 
			
         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty = "(ContentControl.Content)"
            Storyboard.TargetName = "button"> 
            <DiscreteObjectKeyFrame KeyTime = "0" Value = "Play"/> 
         </ObjectAnimationUsingKeyFrames>
			
         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty = "(ContentControl.Content)"
            Storyboard.TargetName = "button1"> 
            <DiscreteObjectKeyFrame KeyTime = "0" Value = "Stop"/> 
            <DiscreteObjectKeyFrame KeyTime = "0:0:2" Value = "Stop"/> 
         </ObjectAnimationUsingKeyFrames> 
      </Storyboard> 
   </Window.Resources> 
	
   <Window.Triggers> 
      <EventTrigger RoutedEvent = "FrameworkElement.Loaded"> 
         <BeginStoryboard Storyboard = "{StaticResource Storyboard1}"/> 
      </EventTrigger> 
   </Window.Triggers> 
	
   <Grid> 
      <Ellipse x:Name = "ellipse" Fill = "#FFAAAAC5" HorizontalAlignment = "Left"
         Height = "50.901" Margin = "49.324,70.922,0,0" Stroke = "Black"
         VerticalAlignment = "Top" Width = "73.684" RenderTransformOrigin = "0.5,0.5"> 
         <Ellipse.RenderTransform> 
            <TransformGroup> 
               <ScaleTransform/> 
               <SkewTransform/> 
               <RotateTransform/> 
               <TranslateTransform/> 
            </TransformGroup> 
         </Ellipse.RenderTransform> 
      </Ellipse>
		
      <Button x:Name = "button" Content = "Play" HorizontalAlignment = "Left" Height = "24.238"
         Margin = "63.867,0,0,92.953" VerticalAlignment = "Bottom" Width = "74.654"> 
         <i:Interaction.Triggers> 
            <i:EventTrigger EventName = "Click"> 
               <ei:ControlStoryboardAction Storyboard = "{StaticResource Storyboard1}"/> 
            </i:EventTrigger> 
         </i:Interaction.Triggers> 
      </Button>
		
      <Button x:Name = "button1" Content = "Stop" HorizontalAlignment = "Left" Height = "24.239"
         Margin = "160.82,0,0,93.922" VerticalAlignment = "Bottom" Width = "75.138"> 
         <i:Interaction.Triggers> 
            <i:EventTrigger EventName = "Click"> 
               <ei:ControlStoryboardAction ControlStoryboardOption = "Stop"
                  Storyboard = "{StaticResource Storyboard1}"/> 
            </i:EventTrigger> 
         </i:Interaction.Triggers> 
      </Button> 
		
   </Grid> 
</Window>

上記のコードをコンパイルして実行すると、楕円と2つのボタンを含む次のウィンドウが生成されます。

再生ボタンを押すと、左から右に動き始め、元の位置に戻ります。停止ボタンは、楕円の動きを停止します。

ドラッグアンドドロップ

ユーザーインターフェイスでのドラッグアンドドロップにより、アプリケーションの効率と生産性を大幅に向上させることができます。実装が難しいと思われるため、ドラッグアンドドロップ機能を使用するアプリケーションはほとんどありません。ドラッグアンドドロップ機能を処理することはある程度困難ですが、WPFでは非常に簡単に処理できます。

それがどのように機能するかを理解するために簡単な例を見てみましょう。ある長方形から別の長方形に色をドラッグアンドドロップできるアプリケーションを作成します。

  • WPFDragAndDropという名前で新しいWPFプロジェクトを作成します。

  • 5つの長方形をデザインウィンドウにドラッグし、次のXAMLファイルに示すようにプロパティを設定します。

<Window x:Class = "WPFDragAndDrop.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFDragAndDrop" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "402.551" Width = "604"> 
	
   <Grid> 
      <Rectangle Name = "Target" Fill = "AliceBlue" HorizontalAlignment = "Left"  
         Height = "345" Margin = "10,10,0,0" Stroke = "Black"  
         VerticalAlignment = "Top" Width = "387" AllowDrop = "True" Drop = "Target_Drop"/> 
			
      <Rectangle Fill = "Beige" HorizontalAlignment = "Left" Height = "65"  
         Margin = "402,10,0,0" Stroke = "Black" VerticalAlignment = "Top"  
         Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
			
      <Rectangle Fill = "LightBlue" HorizontalAlignment = "Left" Height = "65"  
         Margin = "402,80,0,0" Stroke = "Black" VerticalAlignment = "Top"  
         Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
			
      <Rectangle Fill = "LightCoral" HorizontalAlignment = "Left" Height = "65"  
         Margin = "402,150,0,0" Stroke = "Black" VerticalAlignment = "Top"  
         Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
			
      <Rectangle Fill = "LightGray" HorizontalAlignment = "Left" Height = "65"  
         Margin = "402,220,0,0" Stroke = "Black" VerticalAlignment = "Top"  
         Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> 
			
      <Rectangle Fill = "OliveDrab" HorizontalAlignment = "Left" Height = "65"  
         Margin = "402,290,0,-7" Stroke = "Black" VerticalAlignment = "Top"  
         Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/>  
   </Grid> 
	
</Window>
  • 最初の長方形はターゲット長方形であるため、ユーザーは他の長方形からターゲット長方形に色をドラッグできます。

  • 以下に、ドラッグアンドドロップ用のC#でのイベントの実装を示します。

using System.Windows; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Shapes; 
 
namespace WPFDragAndDrop { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
      }  
		
      private void Rect_MLButtonDown(object sender, MouseButtonEventArgs e) { 
         Rectangle rc = sender as Rectangle; 
         DataObject data = new DataObject(rc.Fill); 
         DragDrop.DoDragDrop(rc, data,DragDropEffects.Move); 
      }  
		
      private void Target_Drop(object sender, DragEventArgs e) { 
         SolidColorBrush scb = (SolidColorBrush)e.Data.GetData(typeof(SolidColorBrush)); 
         Target.Fill = scb; 
      } 
   } 
}

アプリケーションを実行すると、次のウィンドウが表示されます。

右側の長方形から色をドラッグして左側の大きな長方形にドロップすると、すぐにその効果がわかります。

4番目を右側からドラッグしてみましょう。

ターゲットの長方形の色が変わったことがわかります。上記のコードを実行して、その機能を試すことをお勧めします。

WPFは、アプリケーションの要件に応じて拡張できる幅広い2Dグラフィックスを提供します。WPFは、グラフィックコンテンツの描画に使用されるDrawingオブジェクトとShapeオブジェクトの両方をサポートします。

形とデッサン

  • ShapeクラスはFrameworkElementクラスから派生し、Shapeオブジェクトはパネルおよびほとんどのコントロール内で使用できます。

  • WPFは、Ellipse、Line、Path、Polygon、Polyline、RectangleなどのShapeクラスから派生したいくつかの基本的なシェイプオブジェクトを提供します。

  • 一方、描画オブジェクトはFrameworkElementクラスから派生せず、より軽量な実装を提供します。

  • 描画オブジェクトは、Shapeオブジェクトと比較して単純です。また、パフォーマンス特性も優れています。

さまざまなシェイプオブジェクトの使用方法を理解するために、簡単な例を見てみましょう。

  • 名前で新しいWPFプロジェクトを作成します WPF2DGraphics

  • 次のコードは、さまざまなタイプの形状を作成します。

<Window x:Class = "WPF2DGraphics.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPF2DGraphics" 
   xmlns:PresentationOptions = "http://schemas.microsoft.com/winfx/2006/xaml/present ation/options"  
   mc:Ignorable = "PresentationOptions" Title = "MainWindow" Height = "400" Width = "604"> 
	
   <StackPanel> 
      <Ellipse Width = "100" Height = "60" Name = "sample" Margin = "10"> 
         <Ellipse.Fill> 
            <RadialGradientBrush> 
               <GradientStop Offset = "0" Color = "AliceBlue"/> 
               <GradientStop Offset = "1" Color = "Gray"/> 
               <GradientStop Offset = "2" Color = "Red"/> 
            </RadialGradientBrush> 
         </Ellipse.Fill> 
      </Ellipse>
		
      <Path Stroke = "Red" StrokeThickness = "5" Data = "M 10,70 L 200,70"
         Height = "42.085" Stretch = "Fill" Margin = "140.598,0,146.581,0" /> 
      <Path Stroke = "BlueViolet" StrokeThickness = "5" Data = "M 20,100 A 100,56 42 1 0 200,10"
         Height = "81.316" Stretch = "Fill" Margin = "236.325,0,211.396,0" /> 
			
      <Path Fill = "LightCoral" Margin = "201.424,0,236.325,0"
         Stretch = "Fill" Height = "124.929"> 
         <Path.Data> 
            <PathGeometry> 
               <PathFigure StartPoint = "50,0" IsClosed = "True"> 
                  <LineSegment Point = "100,50"/> 
                  <LineSegment Point = "50,100"/> 
                  <LineSegment Point = "0,50"/> 
               </PathFigure> 
            </PathGeometry> 
         </Path.Data> 
      </Path> 
		
   </StackPanel> 
	
</Window>

上記のコードをコンパイルして実行すると、楕円、直線、円弧、および多角形が生成されます。

図面で領域をペイントする方法を示す別の例を見てみましょう。

  • 名前で新しいWPFプロジェクトを作成します WPF2DGraphics1

  • 次のXAMLコードは、画像描画で異なるペイントを行う方法を示しています。

<Window x:Class = "WPF2DGraphics1.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:PresentationOptions = "http://schemas.microsoft.com/winfx/2006/xaml/present ation/options"  
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "PresentationOptions" 
   xmlns:local = "clr-namespace:WPF2DGraphics1" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Border BorderBrush = "Gray" BorderThickness = "1"  
         HorizontalAlignment = "Left" VerticalAlignment = "Top" 
         Margin = "20"> 
			
         <Image Stretch = "None">
            <Image.Source> 
               <DrawingImage PresentationOptions:Freeze = "True"> 
					
                  <DrawingImage.Drawing> 
                     <DrawingGroup> 
                        <ImageDrawing Rect = "300,100,300,180" ImageSource = "Images\DSC_0104.JPG"/> 
                        <ImageDrawing Rect = "0,100,250,100" ImageSource = "Images\DSC_0104.JPG"/> 
                        <ImageDrawing Rect = "150,0,25,25" ImageSource = "Images\DSC_0104.JPG"/> 
                        <ImageDrawing Rect = "0,0,75,75" ImageSource = "Images\DSC_0104.JPG"/> 
                     </DrawingGroup> 
                  </DrawingImage.Drawing> 
						
               </DrawingImage> 
            </Image.Source> 
         </Image> 
			
      </Border> 
   </Grid> 
	
</Window>

アプリケーションを実行すると、次の出力が生成されます-

上記のコードを実行して、さらに2D形状と図面を試すことをお勧めします。

Windows Presentation Foundation(WPF)は、アプリケーションの要件に応じて3Dグラフィックスを描画、変換、およびアニメーション化する機能を提供します。本格的な3Dゲーム開発はサポートしていませんが、ある程度は3Dグラフィックスを作成できます。

2Dグラフィックと3Dグラフィックを組み合わせることで、豊富なコントロールを作成したり、データの複雑なイラストを提供したり、アプリケーションのインターフェイスのユーザーエクスペリエンスを向上させたりすることもできます。Viewport3D要素は、3DモデルをWPFアプリケーションにホストします。

3Dグラフィックスの使用方法を理解するために簡単な例を見てみましょう。

  • 名前で新しいWPFプロジェクトを作成します WPF3DGraphics

  • 次のXAMLコードは、3Dジオメトリでを使用して2Dオブジェクトを作成する方法を示しています。

<Window x:Class = "WPF3DGraphics.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPF3DGraphics" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "500" Width = "604"> 
	
   <Grid> 
      <Viewport3D> 
		
         <Viewport3D.Camera> 
            <PerspectiveCamera Position = "2,0,10" LookDirection = "0.2,0.4,-1"
               FieldOfView = "65" UpDirection = "0,1,0" /> 
         </Viewport3D.Camera> 
			
         <ModelVisual3D> 
            <ModelVisual3D.Content> 
               <Model3DGroup> 
                  <AmbientLight Color = "Bisque" /> 
						
                  <GeometryModel3D> 
                     <GeometryModel3D.Geometry> 
                        <MeshGeometry3D Positions = "0,0,0 0,8,0 10,0,0 8,8,0"
                           Normals = "0,0,1 0,0,1 0,0,1 0,0,1" TriangleIndices = "0,2,1 1,2,3"/> 
                     </GeometryModel3D.Geometry>
							
                     <GeometryModel3D.Material> 
                        <DiffuseMaterial Brush = "Bisque" /> 
                     </GeometryModel3D.Material> 
                  </GeometryModel3D>
						
               </Model3DGroup> 
            </ModelVisual3D.Content> 
         </ModelVisual3D> 
			
      </Viewport3D> 
   </Grid> 
	
</Window>

上記のコードをコンパイルして実行すると、3Dで2Dオブジェクトが生成されます。

3Dオブジェクトを示す別の例を見てみましょう。

  • 名前で新しいWPFプロジェクトを作成します WPF3DGraphics1

  • 次のXAMLコードは、3Dオブジェクトとスライダーを作成します。スライダーを使用して、この3Dオブジェクトを回転させることができます。

<Window x:Class = "WPF3DGraphics1.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPF3DGraphics1" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid>
      <Viewport3D Name="viewport3D1">
		
         <Viewport3D.Camera> 
            <PerspectiveCamera x:Name = "camMain" Position = "6 5 4" LookDirection = "-6 -5 -4"> 
            </PerspectiveCamera> 
         </Viewport3D.Camera>
		
         <ModelVisual3D> 
            <ModelVisual3D.Content> 
               <DirectionalLight x:Name = "dirLightMain" Direction = "-1,-1,-1"> 
               </DirectionalLight> 
            </ModelVisual3D.Content> 
         </ModelVisual3D>
		
         <ModelVisual3D x:Name = "MyModel"> 
            <ModelVisual3D.Content> 
               <GeometryModel3D>
				
                  <GeometryModel3D.Geometry>
                     <MeshGeometry3D x:Name = "meshMain"
                        Positions = "0 0 0  1 0 0  0 1 0  1 1 0  0 0 1  1 0 1  0 1 1  0 1 1"  
                        TriangleIndices = "2 3 1  3 1 0  7 1 3  7 5 1  6 5 7  6 4 5  6 2 0
                        2 0 4  2 7 3  2 6 7  0 1 5  0 5 4"> 
                     </MeshGeometry3D> 
                  </GeometryModel3D.Geometry> 
					
                  <GeometryModel3D.Material> 
                     <DiffuseMaterial x:Name = "matDiffuseMain">
                        <DiffuseMaterial.Brush> 
                           <SolidColorBrush Color = "Bisque"/> 
                        </DiffuseMaterial.Brush> 
                     </DiffuseMaterial> 
                  </GeometryModel3D.Material> 
					
               </GeometryModel3D>
            </ModelVisual3D.Content>
			 
            <ModelVisual3D.Transform>                         
               <RotateTransform3D> 
                  <RotateTransform3D.Rotation> 
                     <AxisAngleRotation3D x:Name = "rotate" Axis = "1 2 1"/> 
                  </RotateTransform3D.Rotation> 
               </RotateTransform3D>
            </ModelVisual3D.Transform> 
			 
         </ModelVisual3D> 
      </Viewport3D>
		
      <Slider Height = "23" HorizontalAlignment = "Left"  
         Margin = "145,271,0,0" Name = "slider1" 
         VerticalAlignment = "Top" Width = "269"  
         Maximum = "360" 
         Value = "{Binding ElementName = rotate, Path=Angle}" /> 
			
   </Grid> 
	
</Window>

アプリケーションを実行すると、ウィンドウ上に3Dオブジェクトとスライダーが生成されます。

スライダーをスライドすると、ウィンドウ上のオブジェクトも回転します。

上記のコードを実行して、さらに3Dジオメトリを試すことをお勧めします。

WPFアプリケーションは、を使用してビデオとオーディオをサポートします MediaElement。これにより、オーディオとビデオをアプリケーションに統合できます。MediaElementクラスは、Imageクラスと同じように機能します。メディアに向けるだけでレンダリングされます。主な違いは動画になることですが、オーディオのみを含み、MP3などのビデオを含まないファイルをポイントすると、画面に何も表示されずに再生されます。

WPFは、マシンの構成に応じて、すべての種類のビデオ/オーディオ形式をサポートします。メディアファイルがメディアプレーヤーを再生する場合、同じマシンのWPFでも機能します。

マルチメディアをアプリケーションに統合する方法を理解するために例を見てみましょう。

  • 名前で新しいWPFプロジェクトを作成します WPFMultimedia

  • 次のXAMLコードは、メディア要素と3つのボタンを作成し、いくつかのプロパティでそれらを初期化します。

<Window x:Class = "WPFMultimedia.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFMultimedia" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <StackPanel HorizontalAlignment = "Center" VerticalAlignment = "Center"> 
         <MediaElement Name = "myMedia" Source = "D:\MicrosoftMVA.mp4" 
            LoadedBehavior = "Manual" Width = "591" Height = "274" /> 
         <StackPanel Orientation = "Horizontal" Margin = "0,10,0,0">
            <Button Content = "Play" Margin = "0,0,10,0" Padding = "5" Click = "mediaPlay" /> 
            <Button Content = "Pause" Margin = "0,0,10,0" Padding = "5" Click = "mediaPause" />
            <Button x:Name = "muteButt" Content = "Mute" Padding = "5" Click = "mediaMute" /> 
         </StackPanel> 
      </StackPanel>
   </Grid> 
	
</Window>

さまざまなボタンのC#でのClickイベントの実装を次に示します。

using System; 
using System.Windows; 
 
namespace WPFMultimedia { 

   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
         myMedia.Volume = 100; 
         myMedia.Play(); 
      } 
		
      void mediaPlay(Object sender, EventArgs e) { 
         myMedia.Play(); 
      }  
		
      void mediaPause(Object sender, EventArgs e) { 
         myMedia.Pause();
      } 
		
      void mediaMute(Object sender, EventArgs e) { 
		
         if (myMedia.Volume == 100) { 
            myMedia.Volume = 0; 
            muteButt.Content = "Listen"; 
         } 
         else { 
            myMedia.Volume = 100; 
            muteButt.Content = "Mute"; 
         } 
      } 
   } 
}

上記のコードをコンパイルして実行すると、次のウィンドウが表示されます。3つのボタンを使用して、ビデオを再生し、その再生を制御できます。

ボタンを使用すると、ビデオを一時停止、ミュート、および再生できます。

音声シンセサイザー

WPFには、テキストを音声に変換する機能があります。このAPIはSystem.Speech名前空間に含まれています。SpeechSynthesizer クラスはテキストを話し言葉に変換します。

簡単な例を見てみましょう。

  • 名前で新しいWPFプロジェクトを作成します WPFTextToSpeech

  • の参照として追加するには、System.Speechアセンブリが必要です。 SpeechSynthesizer 働くクラス。

  • 「参照」を右クリックして、「参照の追加」を選択します。

  • ReferenceManagerダイアログが開きます。次に、System.Speechチェックボックスをオンにします

  • [OK]ボタンをクリックします。System.Speechアセンブリはリファレンスで確認できます。

  • 次に、ボタンとテキストボックスをツールボックスからデザインウィンドウにドラッグします。

  • 次のXAMLコードは、ボタンとテキストボックスを作成し、いくつかのプロパティでそれらを初期化します。

<Window x:Class = "WPFTextToSpeech.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:WPFTextToSpeech"
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button x:Name = "button" Content = "Speak"  
         HorizontalAlignment = "Left" Margin = "218,176,0,0"  
         VerticalAlignment = "Top" Width = "75"/> 
			
      <TextBox x:Name = "textBox" HorizontalAlignment = "Left"  
         Height = "23" Margin = "60,104,0,0" TextWrapping = "Wrap"  
         VerticalAlignment = "Top" Width = "418"/> 
   </Grid> 
	
</Window>
  • これは、テキストボックス内のテキストを話し言葉に変換するC#の簡単な実装です。

using System.Speech.Synthesis; 
using System.Windows; 
 
namespace WPFTextToSpeech { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window { 
	
      public MainWindow() { 
         InitializeComponent(); 
      } 
		
      private void button_Click(object sender, RoutedEventArgs e) { 
		
         if (textBox.Text != "") {
            SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(); 
            speechSynthesizer.Speak(textBox.Text);  
         } 
         else { 
            MessageBox.Show("Write some thing in the textbox!");
         } 
      } 
   }
}

上記のコードをコンパイルして実行すると、次のウィンドウが表示されます。次に、テキストボックス内にHello Worldと入力し、[話す]ボタンをクリックします。

「HelloWorld」というサウンドを生成します。テキストボックスに何も入力しないと、次のメッセージが点滅します。

上記の例を実行することをお勧めします。