Windows Forms アプリケーションで WPF コントロールをホストする

0 ユーザーが評価
この投稿には確認済みの回答があります。 0 返信 | 1 サポーター

トップ 10 投稿者 
女性
投稿 22
IG Employee

元記事 (英語): Andrew Flick - http://community.infragistics.com/wpf/articles/hosting-a-wpf-control-in-a-windows-forms-application.aspx

Windows Forms アプリケーションで WPF コントロールをホストする

作業の開始

既存のアプリケーションを次世代アプリケーションに変換する開発方式の 1 つとして「WPF to Windows Forms Interop」があります。WPF はアプリケーションの視覚化で簡単に新しいユーザー エクスペリエンスを作成する機能を提供します。Windows Forms は、フレームワーク、ツール、そして長年の開発による高度な機能を提供します。Windows Forms のレガシー アプリケーションの情報を新しい方法で視覚化するには、Interop を使用します。

Infragistics WPF コントロールは情報の視覚化し、ナビゲーション項目を作成する新しい方法を提供します。存在の Windows Forms アプリケーションに WPF コントロールを追加できます。

参照の追加

統合の手順として、まず WPF コントロール (この例では XamDataPresenter) を Windows Forms アプリケーションに追加します。最初に WPF を処理する以下の Microsoft WPF アセンブリへの参照を追加する必要があります。

  • PresentationFramework
  • PresentationCore
  • WindowsBase
  • WindowsFormsIntegration

Microsoft アセンブリへの参照を追加した後に、以下の Infragistics アセンブリへの参照を追加します。

  • Infragistics3.Windows.DataPresenter.v7.1
  • Infragistics3.Windows.v7.1
  • Infragistics3.Windows.Editors.v7.1

Windows Forms アプリケーションの ElementHost xamDataPresenter をホストする

次に、Windows Forms アプリケーションで WPF コントロールをホストするためのコードを追加します。このサンプルの場合、Form_Load イベントでコア ロジックを実行します。WPF コントロールなどの要素を含む ElementHost オブジェクトと呼ばれるコンテナーがこのコードで大切です。

XamDataPresenter のインスタンスを作成して DataSource プロパティを設定します。XamDataPresenter を ElementHost オブジェクトの子として関連付けます。コードは以下のようになります。

  1. ...  
  2. using System.Windows.Forms.Integration;  
  3. ...  
  4.   
  5. namespace WindowsForms_WPF_InteropDemo  
  6. {  
  7.     public partial class Main: Form  
  8.     {  
  9.         private ElementHost XamHost;  
  10.         private Infragistics.Windows.DataPresenter.XamDataPresenter XamDP;  
  11.         ...  
  12.   
  13.         private void Form1_Load(object sender, EventArgs e)  
  14.         {  
  15.             XamHost = new ElementHost();  
  16.             XamHost.Dock = DockStyle.Fill;  
  17.             this.Controls.Add(XamHost);  
  18.             XamDP = new Infragistics.Windows.DataPresenter.XamDataPresenter();  
  19.             XamDP.DataSource = this.vSalesPersonSalesByFiscalYearsBindingSource;  
  20.             XamHost.Child = XamDP;  
  21.   
  22.         }  
  23. ...  

 

この実装は簡単で、数行のコードでフル XamDataPresenter オブジェクト モデルにアクセスできます。開発者は Visual Studio で XamDataPresenter コントロールを使用できます。

WPF のデザインと Windows Forms のビルド

WPF 開発の核となる概念はデザインと開発を分けて考えることです。たとえば、XamDataPresenter を Blend でスタイル設定し、高度な UX を作成できます。Blend で「ダミー」コントロールにスタイルを設定して、Windows Forms プロジェクトに XAML コードをコピーできますが、効率的ではないため、2 つのツール環境のコミュニケーションを切り離します。WPF スタイル機能を完全に使用するには、他の方法を使用したほうがよいでしょう。

この問題を回避するには、XamDataPresenter をホストする WPF コントロール ライブラリを作成します。これによって、Blend でコントロールをスタイルでき、Visual Studio で ElementHost 内コントロールとして ControlLibrary をホストできます。(注: コントロール ライブラリを Blend でビルドできますが、テストまたは実行するには、ダミー プロジェクトに追加する必要があります。)

最初に問題となるのは、割り当てられたデータ ソースがないことです。これは、データソースとしてシンプルな XML ファイルを作成することで回避できます。そして、それを XamDataPresenter をスタイルために使用できます。あるいは、BindToSampleData プロパティを設定して、XamDataPresenter はサンプル データを使用して、コントロールのスタイル設定をカスタマイズできます。コントロールを視覚的にスタイル設定し、カスタム プレゼンターを追加するなどのデザイナー機能を使用できます。

デザインを変更した後に、プロジェクトをビルドして、Windows Forms ソリューションにプロジェクトを追加するか、Windows Forms プロジェクトの参照フォルダーにカスタム コントロールの DLL を追加します。

WPF プロパティを公開する

Visual Studio では、上記で説明した方法で UserControl を要素ホストに関連付けます。そこで、DataSource プロパティが見つかりないという問題と、最初のサンプルの馴染みのあるプロパティが見つかりません。実際には、XamDataPresenter のプロパティの代わりに、UserControl のプロパティが表示されます。Blend でコントロールのスタイル設定が可能で、Visual Studio でコードを書けるとよいでしょう。このために、XamDataPresenter のプロパティを公開するコードを UserControl に追加する必要があります。

始めに、XamDataPresenter の DataSource プロパティにアクセスできるためのパブリック プロパティを UserControl に追加します。コードは以下のようになります。

  1. public System.Collections.IEnumerable DataSource  
  2. {  
  3.     get { return this.XamDataPresenterInternal.DataSource; }  
  4.     set { this.XamDataPresenterInternal.DataSource = value; }  
  5. }  


WPF
イベントへのリスナー

UserControl のパブリック プロパティとして関連付けして、基本の XamDataPresenter の必要なプロパティを公開できます。また、基本プロジェクトにイベントを公開する必要もあります。このサンプルでは、グリッド セルの編集モードを終了する前にセル値を検証するイベントを追加します。Windows Forms アプリケーションで EditModeEndingEvent が使用できないため、Windows Forms アプリケーション内で基本 XamDataPresenter の EditModeEndingEvent を処理するパブリック イベントをユーザー コントロールに作成します。次のコードを xaml.cs ファイルに追加します。

 

  1. public static RoutedEvent EditModeEndingEvent = EventManager.RegisterRoutedEvent  
  2.    ("EditModeEnding", RoutingStrategy.Bubble, typeof(RoutedEventHandler),  
  3.    typeof(XamDataPresenterWrapper));  
  4.   
  5. public event RoutedEventHandler EditModeEnding  
  6. {  
  7.     add { AddHandler(EditModeEndingEvent, value); }  
  8.     remove { RemoveHandler(EditModeEndingEvent, value); }  
  9. }  
  10.   
  11.    
  12. void XamDataPresenterInternal_EditModeEnding(object sender,  
  13.    Infragistics.Windows.DataPresenter.Events.EditModeEndingEventArgs e)  
  14. {  
  15.   RaiseEvent(new  
  16.      RoutedEventArgs(XamDataPresenterWrapper.EditModeEndingEvent, e));  
  17. }  

.xaml ファイルでイベントを登録します。

  1. <igDP:XamDataPresenter Name="XamDataPresenterInternal"  
  2.  EditModeEnding="XamDataPresenterInternal_EditModeEnding"/>  

WPF コントロール ライブラリを Windows Forms プロジェクトに接続する

ControlLibrary で変更を処理したため、WPF プロジェクトをビルドして、Windows Forms プロジェクトに WPF アプリケーションを追加します。DataSource プロパティを設定します。

  1. ...  
  2. using System.Windows.Forms.Integration;  
  3. ...  
  4.   
  5. namespace WindowsForms_WPF_InteropDemo  
  6. {  
  7.     public partial class Main: Form  
  8.     {  
  9.         private ElementHost XamHost;  
  10.         private Infragistics.XamDataPresenterWrapper XamDataPresenter;  
  11.         ...  
  12.         private void Main_Load(object sender, EventArgs e)  
  13.         {  
  14.             ...  
  15.             XamHost = new ElementHost();  
  16.             XamHost.Dock = DockStyle.Fill;  
  17.             this.Controls.Add(XamHost);  
  18.             XamDataPresenter = new Infragistics.XamDataPresenterWrapper();  
  19.             XamDataPresenter.DataSource =  
  20.                 this.vSalesPersonSalesByFiscalYearsBindingSource;  
  21.             XamHost.Child = XamDataPresenter;  
  22.         }  
  23.   
  24. ...  

その後で、イベントをフックして、そのイベントで処理するロジックを実行できます。このサンプルでは、イベント ハンドラーを (Main_Load) Form_Load イベントに追加して、必要なロジックを実行するコードを追加します。

  1. ...  
  2. using Infragistics.Windows.DataPresenter.Events;  
  3. ...  
  4.   
  5. XamDataPresenter.EditModeEnding +=   
  6.   new System.Windows.RoutedEventHandler(XamDataPresenter_EditModeEnding);  
  7.   
  8. ...  
  9.   
  10. void XamDataPresenter_EditModeEnding(object sender, System.Windows.RoutedEventArgs e)  
  11. {  
  12.     // 編集モードの終了イベントの引数 
  13.     EditModeEndingEventArgs editEndingArgs = e.OriginalSource as  
  14.         EditModeEndingEventArgs;  
  15.       
  16.     if (editEndingArgs == null)  
  17.         return;  
  18.   
  19.     // 編集しているフィールドの列名 (Infragistics.Windows.DataPresenter.Events) 
  20.     string columnName = editEndingArgs.Cell.Field.Name;  
  21.   
  22.     // 編集した後のセル値  
  23.     string newCellValue = editEndingArgs.Editor.Text;  
  24.   
  25.     if (columnName == "Title" )  
  26.     {  
  27.         // 新しいセル値が「Sales Representative」以外の値に変更された場合
  28.         if (newCellValue != "Sales Representative")  
  29.         {  
  30.             //変更を保存しません      
  31.             editEndingArgs.AcceptChanges = false;  
  32.             MessageBox.Show("Title Must Be Sales Representative");  
  33.         }  
  34.     }  
  35. }  
  36. ...  

この場合では、「Sales Representative」セルが変更できないことを実装します。

リッチなクライアント エクスペリエンスを展開する

この手順を完了したで、(アニメーションが表示されない) Windows Forms アプリケーション内で XamDataPresenter のグリッド ビューを表示するスクリーンショットはこれです。

また、このスクリーンショットは Windows Forms アプリケーション内でホストされる XamDataPresenter のカルーセル ビューを表示します。

タイプ依存関係についての注意

注: Windows Forms アプリケーションで Infragistics EditModeEndingEventArgs を使用しています。そのため、Infragistics WPF アセンブリへの参照が必要です。Infragistics WPF の依存関係が使用できない場合、リフレクションを使用できます。NetAdvantage WPF アセンブリの使用を推薦しますが、以下のコードも使用できます。

 

  1. void XamDataPresenter_EditModeEnding(object sender, System.Windows.RoutedEventArgs e)  
  2. {  
  3.     //編集したセル オブジェクトを検索します  
  4.     object cell = e.OriginalSource.GetType().GetProperty("Cell").GetValue(  
  5.         e.OriginalSource, null);  
  6.       
  7.     //セルのフィールドを取得します  
  8.     object field = cell.GetType().GetProperty("Field").GetValue(cell, null);  
  9.   
  10.     //セルのフィールド名を取得します  
  11.     string name = field.GetType().GetProperty("Name").GetValue(field, null) as string;  
  12.    
  13.     //列名が「Title」かどうかを確認します  
  14.     if (name == "Title")      
  15.     {  
  16.         //ユーザーによって入力したテキストを取得します  
  17.         object editor = e.OriginalSource.GetType().GetProperty("Editor").GetValue(  
  18.           e.OriginalSource, null);  
  19.           
  20.         string text = editor.GetType().GetProperty("Text").GetValue(editor, null) as string;  
  21.   
  22.         //テキストが「Sales Representative」かどうかを確認します  
  23.         if (text != "Sales Representative")  
  24.         {  
  25.             e.OriginalSource.GetType().GetProperty("AcceptChanges").SetValue(  
  26.               e.OriginalSource, false, null);  
  27.               
  28.             MessageBox.Show("Title Must Be Sales Representative");  
  29.         }  
  30.     }  
  31. }  

 

まとめ

開発者は、Infragistics が提供するスタイルを使用して、Visual Studio でアプリケーションを作成できます。グラフィック デザイナーがいるか、Blend との操作が必要な場合、コントロールをコントロール ライブラリにラップすることができます。ロールを分割することができます。

最後に、Interop の制限に注意してください。要素ホスト コントロールで 1 つの子コントロールのみがホストできます。WPF と Windows Forms には別のスケール モデルがあります。WindowsFormsHost で ElementHost をネストできない、また ElementHost で WindowsFormsHost をネストできません。制限のリストを表示するには、http://blogs.msdn.com/scoberry/archive/2006/09/01/735844.aspx (英語) を参照してください。.

アプリケーションでリッチなクライアント エクスペリエンスを実現してください。


ページ 1 / 1 (1 項目) | RSS
Infragistics Japan
インフラジスティックス ジャパン