[Xaml Island] 【うまく動かせず断念】.NET core 3.0のWPFでUWPコントロールを使う

**もくじ**
https://tera1707.com/entry/2022/02/06/144447

# やりたいことと、現状のおことわり
お題のとおり、.NET core 3.0のWPFでUWPコントロールを使ってみようとしています。
内容は、勉強のための、[かずきさんブログ](https://blog.okazuki.jp/entry/2019/05/10/041326)のトレースです。

ただ、かずきさんブログを参考にInkCanvasを試しては見たのですが、現状うまく動かすことができませんでした。
感触としては、HDD容量の節約のために、インストールしていないSDKやツールが多数あるせいで、なにかがうまく動いていないような(個人的な)感触です。

なので、下記をそのまま実施しても、うまく動かない可能性が高いです。
今後、再度トライしたときにメンテしようと思うのと、うまくいかない時の事例としてもしかして参考になればと思い、一応書いた分は残します。(見た方を混乱させてしまったら申し訳ありません)

基本、やったことを上から順番に書いてますが、[一番最後](https://qiita.com/drafts/745d3a5ef8f4cefdb623/edit#%E3%81%8B%E3%81%9A%E3%81%8D%E3%81%95%E3%82%93%E3%83%87%E3%83%A2%E3%83%96%E3%83%AD%E3%82%B0%E3%81%AE%E3%81%A8%E3%81%8A%E3%82%8A%E3%81%AB%E3%82%84%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%A6%E3%81%A4%E3%81%BE%E3%81%A5%E3%81%84%E3%81%9F%E9%83%A8%E5%88%86)に、つまった部分をまとめて書いてます。(うまくいかなくてごちゃごちゃいじくりまわしたので、正確でないかもしれません)

# 前提
下記のものを使って、2019年7月上旬に試した。
VisualStudio Community2019 Version 16.1.5
.NET Core3.0 preview5
Microsoft.Toolkit.Wpf.UI.Controls 6.0.0-preview5

# やったこと

### .NET core3.0のインストール
こちらから、インストールした。
https://dotnet.microsoft.com/download/dotnet-core/3.0

試した当時、最新の.NET core3.0はpreview6。(今回試したのは5)
本リリースは2019年11月とのこと。

### VisualStudio2019の設定
VisualStudio2019を起動し、
[ツール] > [環境] > [プレビュー機能] > [.NETコアSDKのプレビューを使用する]
にチェックを入れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/c93f953d-eadb-1bbe-2793-88cf4991cb6a.png)

※[MSの公式ページ？](https://devblogs.microsoft.com/dotnet/net-core-tooling-update-for-visual-studio-2017-version-15-9/)には、
[ツール] > [プロジェクトおよびソリューション] > [.NET Core] >[Use Preview of the .NET core SDK]
にチェックを入れろ、とあるが、そこにはチェックはなかった...
(このページはVS2017の話？？)

### Microsoft.Windows.SDK.ContractsをNugetからとる

**★★今回xaml islandをするうえでは、Microsoft.Windows.SDK.Contractsは不要。**
**★★下で入れるMicrosoft.Toolkit.Wpf.UI.Controlsに、含まれている。**
**★★消すのがもったいないので書いた内容は置いておきますが、読み飛ばして下さい。**

Windows10 APIを使用するために必要。
試した時点では、Ver 10.0.18362.2002-preview ※プレビュー版

以前は、もう少しややこしい手順が必要だったのが、簡単になった。
ややこしい手順＝たぶん[これ](https://docs.microsoft.com/ja-jp/windows/apps/desktop/modernize/desktop-to-uwp-enhance#first-set-up-your-project)のこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/163c274e-f20a-b48a-72f8-8d8158da5438.png)

NugetにあるMicrosoft.Windows.SDK.Contractsの説明を訳すと、

```
Windows 10 WinRT API Packを使用すると、.NET Framework 4.5以降および.NET Core 3.0以降の
ライブラリおよびアプリケーションに最新のWindowsランタイムAPIサポートを追加できます。
      
このパッケージには、Windows 10バージョン1903までのサポートされている
すべてのWindowsランタイムAPIが含まれています。
```
とのこと。


### Microsoft.Toolkit.Wpf.UI.ControlsをNugetからとる
UWPのコントロールをWPFで使うために必要。
試した時点では Ver 6.0.0-preview5 ※プレビュー版

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/d4f57ed8-dfec-0660-4089-e20578a0308b.png)


### Program.csを追加する
下記の手順で、追加したProgram.csをスタートアッププログラムに指定し、
スタートアップに指定する。

- ソリューションを右クリック> [追加] > [新しい項目] > [クラス]を選択し、Program.csと名付ける
- 下のコードを記述する。
- 
```Program.cs
using Microsoft.Toolkit.Win32.UI.XamlHost;
using System;

namespace WpfApp30
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            using (new XamlApplication())
            {
                var app = new App();
                app.InitializeComponent();
                app.Run();
            }
        }
    }
}

```
- ソリューションのプロパティ > [アプリケーション]の中の[スタートアップオブジェクト]で、作成したProgramクラスを指定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/75c440f2-95fa-3bf1-f5db-3f3ce811745b.png)

### マニフェストファイルの作成
ソリューションを右クリック> [追加] > [新しい項目] > [アプリケーションマニフェストファイル]を選択し、マニフェストファイルを追加する。(今回は名前は適当)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/ba561d6f-37dc-692f-aa24-d957ee7e75af.png)

### マニフェストファイルの修正
作成したマニフェストファイルを開き、下記を行う。

- Windows10が対象OSであることを示すために、Windows10のところのコメントアウトを解除する
- 対象のバージョンが19H1以降であることを示すために、maxversiontestedを追加して、
※これをしないと、xaml islandのライブラリが例外を吐くらしい。[(かずきさんページ)](https://blog.okazuki.jp/entry/2019/05/10/041326)
- dpiAwareの設定を追加する

変更前

```xml
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
　　　・・・
      <!-- Windows 10 -->
      <!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->

    </application>
  </compatibility>
　　　・・・
  <!--
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>
  -->
```

変更後

```xml
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
　　　・・・
      <!-- Windows 10 -->
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
      <maxversiontested Id="10.0.18362.0"/>

    </application>
  </compatibility>
　　　・・・
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
    </windowsSettings>
  </application>
```

### マニフェストファイルの指定
ソリューションのプロパティ > [アプリケーション]の中の[リソース] > [マニフェスト]で、作成したマニフェストを指定する。(自動で設定されているかも)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/ec2219a9-ee13-96c1-4e42-a4079b05601c.png)

### xamlに、UWPのコントロールを配置する
- まず、xaml Islandの名前空間を追加する
- その後、下記のようにコードを書き、UWPのコントロールを配置する（今回は、UWPのInkCanvasを置く）

```MainWindow.xaml
<Window x:Class="WpfApp33.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp33"
        xmlns:toolkit="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <toolkit:InkCanvas  />
    </Grid>
</Window>
```


### ここまでの通りやってみましたが、うまくうごかなかった..
うまく動かない、というのは、ビルドはできて、アプリ実行(F5)もできるが、ウインドウになにも表示されない状態になる(InkCanvasはもちろん、試しにその他配置したもの(Buttonなど)もすべて見えない)、という感じ。
(InkCanvasをはずすと、その他のButtonなどは出てくる)

しばらく寝かせて、近く再トライしたい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/d0401fea-3e80-760c-e79f-06e540e617dc.png)

# かずきさんデモ/ブログのとおりにやってみて、つまづいた部分
- 実験当時、Microsoft.Toolkit.Wpf.UI.Controlsは最新は6.0.0-preview6.3だったが、そのVerだとProgram.csがうまくビルドできなかったので、かずきさんがデモされているpreview5を使用した。（preview6.3だとXamlApplicationクラスがnewできない）
- .NETCore3.0preview6とMicrosoft.Toolkit.Wpf.UI.Controls 6.0.0-preview5の組み合わせだと、こんなエラーがでる？？
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/79ec3fee-6136-b2dc-f4e3-5dfaa36b1d13.png)
- 上のエラーは、.NETcore3.0とNugetしたtoolkitのバージョンの組み合わせではなく、Windows10のバージョンが新しくないため？？？[こちら](https://www.thomasclaudiushuber.com/2019/04/23/net-core-3-use-uwp-controls-in-wpf-with-xaml-islands/)参照（When I run the application, I get an InvalidCastException. とあるところ）
- 今使っていたWindows10は「1809」だった。どうも「1903」以降でないとうごかないっぽい。
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/7429b284-7a88-8d76-d5ff-cc9ecb3bd00b.png)
- 1809→1903にWindowsUpdateしてみて試す→Updateしたが、だめだった。状況変わらず。
- 「ユニバーサルWindowsプラットフォーム開発」のWindows 10 SDK (10.0.18362.0)がインストールされていない。SDKが足りていないから動かないのかも？→インストールしたが、動かず。(ビルドはできて、アプリ実行もできるが、ウインドウになにも表示されない状態になる(InkCanvasはもちろん、その他に配置したものもすべて見えない))
- .NET core3.0のせいかも？→.NET Framework(たしか4.7.2)に変えて同じことをやってみたが、同じような現象になった。(ビルドできてWindowはでるが、真っ白なWindowになる)
- ここまでで、一旦断念...

# その他不明点メモ
- Windows10 API = UWP APIなのか？？用語の理解が追い付いてない。
- あとWindows Runtime APIも。同じものを指してる？？

# 参考

公式ページ
https://docs.microsoft.com/ja-jp/windows/apps/desktop/modernize/xaml-islands

公式ブログ
https://techcommunity.microsoft.com/t5/Windows-Dev-AppConsult/Using-XAML-Islands-on-Windows-10-19H1-fixing-the-quot/ba-p/376330#M117

https://www.thomasclaudiushuber.com/2019/04/23/net-core-3-use-uwp-controls-in-wpf-with-xaml-islands/