Office アドイン Advent Calendar の8日目です。
VSTOでUIを作るのはWindows Formsの方が対応されてはいます。しかし、私を含めWindows デスクトップでGUI作成といえばWPFばかりやってきているので、WPFを使いたい!という人も多いと思います。そこで今日はWPFの画面をVSTOで使う方法を紹介したいと思います。
以前デモを行った、Wordのタスクペインに、Flickrの検索ボタンと画像を選択したらワードに挿入するというアプリを例に使います。
ポイントとしては、WPFのコントロールをUserControlとして作成するのですが、このときUserControlはVSTOのプロジェクトとは別のWPFカスタムコントロールライブラリプロジェクトとして作成しています。
必須ではないのですが、こうしておいた方がUserControlを作成するときのWPFに必要なクラスライブラリの選択が不要だったり、デフォルトでXAMLエディタが起動したりでなにかと楽になります。こうして、UserControlの画面を作成していきます。
次にポイントなるのが、VSTOとWPFでのやり取りになります。今回のケースでは、WPF側で画像をクリック => Wordにクリックされた画像を挿入するためにVSTOのメソッドを呼ぶ、という部分です。VSTOのプロジェクトはWPFのプロジェクトを参照するので、逆の流れ*1であれば、WPF側でメソッドを公開しておいて、それをVSTOが呼ぶということができます。そこでWPF側にイベントハンドラを公開し、VSTO側はそのイベントを購読するようにしました。
VSTOSample/UserControl1.xaml.cs at master · tanaka-takayoshi/VSTOSample · GitHub
VSTOSample/ThisAddIn.cs at master · tanaka-takayoshi/VSTOSample · GitHub
最後にWPFで作ったUserControlをタスクペインに追加する方法ですが、空のタスクペインを作成しておきロード時にElementHost
を動的に追加し、そのElementHost
にUserControl
を追加します。
private void MyTaskPane_Load(object sender, EventArgs e) { var ehost = new ElementHost {Dock = DockStyle.Fill}; MyControl = new UserControl1(); ehost.Child = MyControl; Controls.Add(ehost); }
追加したUserControl
をプロパティで公開しているのは、前述の通りThisAddInからWPFとのやりとりを行うためです。
以上でVSTOでWPFが動かす基本的な内容になります。実際に動かすとこんな感じになります。
参考資料
- Using WPF Controls in Office Solutions
- http://blogs.msdn.com/b/tarok/archive/2007/06/12/vsto-wpf.aspx;title
- c# - How to Use WPF Controls Inside an Excel Actions Pane? - Stack Overflow
*1:今回のケースでは画像挿入が完了したメッセージをSyncメソッドでWPF側に送っている