UWP XAML Hosting API の WindowsXamlHost を利用して Windows FormアプリケーションにUWPボタンを作成する - C#

UWP XAML Hosting API の WindowsXamlHost を利用して Windows FormアプリケーションにUWPボタンを作成するプログラムを紹介します。
注意
この記事で紹介しているプログラムは .NET Framework のWindows Formアプリケーションです。 最新版では、.NET Framework でのUWP XAML Hosting APIはサポートされておらず、この記事の手順では動作しません。

(WindowsXamlHost コントロールをフォームに配置するとエラーが発生します。)

概要

XAML Islands とも呼ばれているUWP XAML Hosting APIを利用してWindows FormからUWPのコントロールを表示して利用します。

プログラム

事前準備

Visual Studio 2017を15.9にアップデートします。今回はVisual Studio 2017 Version 15.9.3 を利用します。

プロジェクトの作成

Windows Formアプリケーションのプロジェクトを作成します。

Microsoft.Toolkit.Forms.UI.Controls のインストール

Microsoft.Toolkit.Forms.UI.Controlsをインストールします。

[ツール]メニューの[NuGet パッケージ マネージャー]メニューの[パッケージ マネージャー コンソール]をクリックします。


ウィンドウ下部のエリア[パッケージ マネージャー コンソール]のウィンドウが表示されます。
下記のコマンドを入力して実行します。
Install-Package Microsoft.Toolkit.Forms.UI.Controls


Microsoft.Toolkit.Forms.UI.Controls のインストールが始まります。

インストールが完了すると下図のインストールに成功した旨のメッセージが表示されます。


[ソリューション エクスプローラー]ウィンドウのプロジェクトのノードの[参照]ノードを展開します。"Microsoft.Toolkit.Forms.UI.Controls" アセンブリや "Microsoft.Toolkit.Forms.UI.XamlHost" アセンブリが参照に追加されていることが確認できます。

Windows.winmd の参照追加

Windows.UI.Xaml.Controls や Windows.UI.Xaml.UIElement を参照できるようにするため、"Windows.winmd"を参照に追加します。ソリューションエクスプローラーウィンドウのプロジェクトノード内の[参照]ノードをクリックして選択し右クリックします。下図のポップアップメニューが表示されますので[参照の追加]メニューをクリックします。


下図の[参照マネージャー]ダイアログが表示されます。ダイアログウィンドウ右下の[参照]ボタンをクリックします。


ファイルを開くダイアログが表示されます。下記のフォルダを開きます。
C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17763.0


デフォルトの状態では、winmd 拡張子は表示されませんので、ウィンドウ右下のコンボボックスをクリックしてドロップダウンリストから[すべてのファイル]をクリックして選択します。


"Windows.minmd" ファイルを開きます。


[参照マネージャー]ダイアログに戻ります。[Windows.minmd]にチェックがついていることを確認し、[OK]ボタンをクリックしてダイアログを閉じます。


[参照]ノードに[Windows]ノードが追加されます。

UI

WindowsXamlHost コントロールの配置

フォームデザイナを表示します。[ツールボックス]ウィンドウに"Microsodft.Toolkit.Forms.UI.XamlHost"グループと"Microsoft.Toolkit.Forms.UI.Controls" グループが追加されています。


Microsodft.Toolkit.Forms.UI.XamlHostグループにある[WindowsXamlHost]コントロールをフォームデザイナのフォームにドラッグ&ドロップします。フォームにWindowsXamlHostコントロールが配置されます。


サイズを変更して下図のUIを作成します。


InitialTypeName プロパティの設定

フォームデザイナのWindowsXamlHostコントロールをクリックして選択します。プロパティウィンドウの"InitialTypeName"プロパティの値を編集します。


"InitialTypeName"プロパティに "Windows.UI.Xaml.Controls.Button" を設定します。

コード

フォームデザイナのWindowsXamlHostコントロールをクリックして選択します。プロパティウィンドウのイベント画面のChildChanged イベントをダブルクリックしてイベントハンドラーを作成します。


コードエディタが表示されます。ChildChangeイベントハンドラーにコードを記述します。


下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Toolkit.Forms.UI.XamlHost;

namespace SimpleUwpButton
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }

    private void windowsXamlHost1_ChildChanged(object sender, EventArgs e)
    {
      WindowsXamlHost host = (WindowsXamlHost)sender;
      Windows.UI.Xaml.Controls.Button button = (Windows.UI.Xaml.Controls.Button)host.Child;
      button.Content = "UWP button";

    }
  }
}

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。WindowsXamlHost コントロール内に UWPのボタンが表示されます。

Clickイベントを実装する

コード

下記のコードを追加してUWPボタンにClickイベントを実装します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Toolkit.Forms.UI.XamlHost;

namespace SimpleUwpButton
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }

    private void windowsXamlHost1_ChildChanged(object sender, EventArgs e)
    {
      WindowsXamlHost host = (WindowsXamlHost)sender;
      Windows.UI.Xaml.Controls.Button button = (Windows.UI.Xaml.Controls.Button)host.Child;
      button.Content = "UWP button";
      button.Click += Button_Click;
    }

    private void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
    {
      MessageBox.Show("UWP button がクリックされました。");
    }
  }
}

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


ボタンをクリックします。下図のメッセージダイアログが表示されます。

Clickイベントで表示されるダイアログをUWPのメッセージダイアログにする

先のコードでボタンクリック時にメッセージダイアログを表示する動作を実装できましたが、メッセージダイアログは従来のWindowsのダイアログです。コードを編集してUWPのメッセージダイアログが表示できるようにします。UWPのメッセージダイアログの表示の詳細はこちらの記事を参照してください。

System.Runtime.WindowsRuntime アセンブリ参照の追加

メッセージダイアログを表示する際にawaitを利用します。awaitを利用するためにSystem.Runtime.WindowsRuntime アセンブリを追加します。
ソリューションエクスプローラーでアセンブリの参照を追加します。下記のフォルダの "System.Runtime.WindowsRuntime.dll" を参照に追加します。
C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17763.0 C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll



[参照]ノードに "System.Runtime.WindowsRuntime" が追加されます。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Toolkit.Forms.UI.XamlHost;

namespace SimpleUwpButton
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }

    private void windowsXamlHost1_ChildChanged(object sender, EventArgs e)
    {
      WindowsXamlHost host = (WindowsXamlHost)sender;
      Windows.UI.Xaml.Controls.Button button = (Windows.UI.Xaml.Controls.Button)host.Child;
      button.Content = "UWP button";
      button.Click += Button_Click;
    }

    private async void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
    {
      Windows.UI.Popups.MessageDialog md = new Windows.UI.Popups.MessageDialog("UWP buttonがクリックされました。");
      await md.ShowAsync();
    }
  }
}

解説

下記のコードにより、Windows.UI.Popups.MessageDialog オブジェクトのインスタンスを作成します。コンストラクタの引数にメッセージダイアログに表示する文字列を与えます。
  Windows.UI.Popups.MessageDialog md = new Windows.UI.Popups.MessageDialog("UWP buttonがクリックされました。");

MessageDialog オブジェクトの ShowAsyncメソッドを呼び出しメッセージダイアログを表示します。ShowAsyncは非同期メソッドのため、後続の処理がある場合は実行されてしまします。処理をブロックするため、await を指定します。
  await md.ShowAsync();

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


ボタンをクリックします。下図のメッセージダイアログが表示されます。UWPスタイルのメッセージダイアログが表示されます。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2018-12-08
iPentec all rights reserverd.