WPF のアプリケーションで TextBlock コントロールに UnicodeのEmoji を色付き絵文字として表示したいということで、試行錯誤していい感じに使えるようになったので、記事にしておきます。
実現したいこととしては、次の3点がありました。
- UnicodeのEmoji を色付き絵文字として表示したい。
- リンク付きのテキスト表示を行いたい。
- View Model からデータ表示を行いたい。
WPF の TextBlock コントロールは色付き絵文字の表示をサポートしていませんが、UWP の TextBlock コントロールは色付き絵文字の表示をサポートしています。ただ、Win32 アプリケーションである WPF から UWP のコントロールを利用することはできないため、Win32 アプリケーションから UWP のコントロールを利用可能にする XAML Islands を使う必要があります。
また、リンク付きテキストの表示は、Inline クラスを継承した ContentLink クラスを利用することで可能となりますが、これを TextBlock コントロールで表示させるための TextBlock.Inlines プロパティは依存関係プロパティではないため、直接 TextBlock のインスタンスにアクセスする必要があります。
これらを解決するために最終的に参考にしたのは、Microsoft の Documentation “WindowsXamlHost control for Windows Forms and WPF” になります(WindowsXamlHost は XAML Islands が提供する機能の一部です)。
なお、Microsoft ではユーザーインターフェイス(UI)部分を Win32 アプリケーションと UWP から統一的に利用できるようにする Windows UI Library (WinUI) というプロジェクトを進めていて(XAML Islands もその成果の一部です。)、2020年7月現在、一般公開版の 2.x がリリースされています。次期リリース予定の WinUI 3.0 ではさらに使いやすくなるようですが、とりあえず、現在使えるものでアプリケーションを組みたいということで、この試行錯誤を行いました。
プロジェクトの作成と環境設定は、次の手順になります。
- WPF App(.NET Core) のプロジェクト テンプレートを利用してプロジェクトを作成する(XAML Islands では .NET Framework はサポートされていません)。
- NuGet から Microsoft.Toolkit.Wpf.UI.XamlHost パッケージをプロジェクトにインストールする。
- プロジェクトにマニフェスト ファイルを追加して Windows 10 バージョン 1903(OS ビルド 18362) 以上での動作に限定させる(「かずきのBlog」さんの「WPF on .NET Core で XAML Islands を使ってみよう」の記事を参考にどうぞ)。
- ターゲット CPU プラットフォームを “Any CPU” から “x86” または “x64” へ変更する(UWP ではターゲット CPU を指定する必要があるため)(Visual Studio のドキュメント「方法: プロジェクトを構成してターゲット プラットフォームを設定する」の記事を参考にどうぞ)。この設定を行っていないと「Windows UI Library (WinUI)コード -1073741819 (0xc0000005) ‘Access violation’ で終了しました。」エラーが発生する場合があります。
作成した UwpTextBlock クラスは次のとおりです。
プログラム全体は GitHub のリポジトリ「WrappedUwpTextControl」に置いておいたので、そちらをご覧ください。TextBlock のソリューションと TextBox のソリューションがあります。
プログラムを動作させたときのスクリーンショットを掲載しておきます。