Windows のバージョン 1809 で XAML Islands (MS のドキュメントの翻訳では XAML 諸島) という機能が使えるようになりました。
Windows 10 の UI コントロール (UWP のコントロール) が WPF や Windows Forms アプリケーションで使える夢の機能です。
詳細は公式ドキュメントへ
WPF で試した記事はこちら
当時と今では状況も違うはずですし今度は Windows フォームアプリケーションで試してみます。
■ NuGet パッケージのインストール
まずは、NuGet で Microsoft.Toolkit.Forms.UI.XamlHost をインストールします。
以前は、プレリリースを含めるのチェックが必要だった記憶がありますが、今は不要のようです。
ダウンロード件数がとても気になりますが今は気にしないでおきましょう。
■ デザイナで XamlHost コントロールを配置
NuGet パッケージをインストールすると、XamlHost コントロールが使えるようになるので、デザイナで配置します。
■ 参照の設定
以前は 6 つほど参照を追加した記憶がありますが、今回は二つだけで済みました。
ファイル | 場所 |
---|---|
Windows.Foundation.UniversalApiContract.winmd | C:\Program Files (x86)\Windows Kits\10\References<sdk version>\Windows.Foundation.UniversalApiContract<version> |
Windows.WinMD | C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Facade |
■ プロパティを設定
XamlHost コントロールは、UWP のコントロールを入れるられるコンテナのようなものです。実際に中に配置するコントロールを設定します。今回もまずは ProgressRing を表示してみます。
XamlHost プロパティを開いて InitialTypeName に Windows.UI.Xaml.Controls.ProgressRing と設定します。
InitialTypeName で指定したコントロールのプロパティをデザイナから設定する手段はありません。実際に生成されたイベントの中で設定をします。
XamlHost の ChildChanged イベントにハンドラを設定します。
デザインのコード
デザインのコードは次のように設定しました。
// // windowsXamlHost1 // this.windowsXamlHost1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly; this.windowsXamlHost1.InitialTypeName = "Windows.UI.Xaml.Controls.ProgressRing"; this.windowsXamlHost1.Location = new System.Drawing.Point(40, 10); this.windowsXamlHost1.Name = "windowsXamlHost1"; this.windowsXamlHost1.Size = new System.Drawing.Size(300, 200); this.windowsXamlHost1.TabIndex = 0; this.windowsXamlHost1.Text = "windowsXamlHost1"; this.windowsXamlHost1.ChildChanged += new System.EventHandler(this.windowsXamlHost1_ChildChanged);
イベントハンドラ
イベントハンドラの中で ProgressRing のプロパティを設定します。
private void windowsXamlHost1_ChildChanged(object sender, EventArgs e) { var host = (Microsoft.Toolkit.Forms.UI.XamlHost.WindowsXamlHost)sender; var progressRing = (Windows.UI.Xaml.Controls.ProgressRing)host.Child; if (progressRing != null) { progressRing.IsActive = true; progressRing.Width = 300; progressRing.Height = 200; } }
■ 実行
実行してみると、UWP の ProgressRing が表示されました。これで時間のかかる処理を行う際も安心ですね。
■ InkCanvas
UWP のコントロールが使えると聞いて皆が気になるあのコントロール InkCanvas も試してみます。
XamlHost コントロールをもう一つ配置して各種設定をして行きます。コントロールの名前は自動で設定された windowsXamlHost2 としています。
デザインのコード
namespace WindowsFormsApp1 { partial class Form1 { /// <summary> /// 必要なデザイナー変数です。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 使用中のリソースをすべてクリーンアップします。 /// </summary> /// <param name="disposing">マネージド リソースを破棄する場合は true を指定し、その他の場合は false を指定します。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows フォーム デザイナーで生成されたコード /// <summary> /// デザイナー サポートに必要なメソッドです。このメソッドの内容を /// コード エディターで変更しないでください。 /// </summary> private void InitializeComponent() { this.windowsXamlHost1 = new Microsoft.Toolkit.Forms.UI.XamlHost.WindowsXamlHost(); this.windowsXamlHost2 = new Microsoft.Toolkit.Forms.UI.XamlHost.WindowsXamlHost(); this.SuspendLayout(); // // windowsXamlHost1 // this.windowsXamlHost1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly; this.windowsXamlHost1.InitialTypeName = "Windows.UI.Xaml.Controls.ProgressRing"; this.windowsXamlHost1.Location = new System.Drawing.Point(40, 10); this.windowsXamlHost1.Name = "windowsXamlHost1"; this.windowsXamlHost1.Size = new System.Drawing.Size(300, 200); this.windowsXamlHost1.TabIndex = 0; this.windowsXamlHost1.Text = "windowsXamlHost1"; this.windowsXamlHost1.ChildChanged += new System.EventHandler(this.windowsXamlHost1_ChildChanged); // // windowsXamlHost2 // this.windowsXamlHost2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly; this.windowsXamlHost2.InitialTypeName = "Windows.UI.Xaml.Controls.InkCanvas"; this.windowsXamlHost2.Location = new System.Drawing.Point(440, 10); this.windowsXamlHost2.Name = "windowsXamlHost2"; this.windowsXamlHost2.Size = new System.Drawing.Size(300, 200); this.windowsXamlHost2.TabIndex = 1; this.windowsXamlHost2.Text = "windowsXamlHost2"; this.windowsXamlHost2.ChildChanged += new System.EventHandler(this.windowsXamlHost2_ChildChanged); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(784, 221); this.Controls.Add(this.windowsXamlHost2); this.Controls.Add(this.windowsXamlHost1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion private Microsoft.Toolkit.Forms.UI.XamlHost.WindowsXamlHost windowsXamlHost1; private Microsoft.Toolkit.Forms.UI.XamlHost.WindowsXamlHost windowsXamlHost2; } }
イベントハンドラ
using System; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void windowsXamlHost1_ChildChanged(object sender, EventArgs e) { var host = (Microsoft.Toolkit.Forms.UI.XamlHost.WindowsXamlHost)sender; var progressRing = (Windows.UI.Xaml.Controls.ProgressRing)host.Child; if (progressRing != null) { progressRing.IsActive = true; progressRing.Width = 300; progressRing.Height = 200; } } private void windowsXamlHost2_ChildChanged(object sender, EventArgs e) { var host = (Microsoft.Toolkit.Forms.UI.XamlHost.WindowsXamlHost)sender; var inkCanvas = (Windows.UI.Xaml.Controls.InkCanvas)host.Child; if (inkCanvas != null) { inkCanvas.Width = 300; inkCanvas.Height = 200; inkCanvas.InkPresenter.InputDeviceTypes = Windows.UI.Core.CoreInputDeviceTypes.Mouse | Windows.UI.Core.CoreInputDeviceTypes.Pen; } } } }
InlCanvas にマウスで書けるように inkCanvas.InkPresenter.InputDeviceTypes = Windows.UI.Core.CoreInputDeviceTypes.Mouse | Windows.UI.Core.CoreInputDeviceTypes.Pen;
という設定を行っています。
■ 実行
実行して文字を書いてみました。これで最新機能を実装する Windows フォームアプリケーションという要件があっても安心ですね。
■ おまけ .NET Core 3.0
以前に .NET Core 3.0 で Windows フォームアプリケーションを作る記事を書きました。
デスクトップアプリも .NET Core で作る時代が近づいています。XAML 諸島が .NET Core でも使えるか試してみました。
結果は
エラー NU1202 パッケージ Microsoft.Toolkit.Forms.UI.XamlHost 5.0.1 は netcoreapp3.0 (.NETCoreApp,Version=v3.0) / win-x64 と互換性がありません。 パッケージ Microsoft.Toolkit.Forms.UI.XamlHost 5.0.1 がサポートするもの: net462 (.NETFramework,Version=v4.6.2)
まだ使えないようです。残念。