rksoftware

Visual Studio とか C# とかが好きです

WPF でUWP の ProgressRing を表示する

以前、WPF で ProgressRing を表示する記事を書きました。 WPF に ProgressRing がないのでライブラリを導入する記事でした。
そして、UWP で ProgressRing を表示する記事も書きました。 UWP には ProgressRing があるのでただ表示するだけという記事でした。

その他進捗中表示シリーズです。

多分、この記事で進捗中表示シリーズの一旦の締めとなると思います。

■ WindowsXamlHost

プレビューではありますが、UWP のコントロールが WPF で使える機能が試せるそうです。 基本はこの非常に素晴らしいブログ記事の通りです。Button コントロールを ProgressRing に変えただけです。

■ 手順補足

私の環境では少し違った手順になりました。違った部分だけメモします。

.NET Framework 4.7.2

.NET Framework 4.7.2 がインストールされていなかったためインストールが必要でした。 インストールはサイトからインストーラーをダウンロードして行いますが、ダウンロードサイトへはプロジェクトのプロパティからいけます。

インストールが完了すれば選択肢に .NET Framework 4.7.2 が追加されます。

Microsoft.Toolkit.Wpf.UI.XamlHost のインストール

これが良いバージョンのパッケージなのかわかりませんが、Package source を追加しなくとも、プレビューを含む チェックの ON でインストールが可能でした。
f:id:rksoftware:20180930215323j:plain

Insider Preview または Visual Studio Preview

動作に、Windows 10 を Insider Preview にしているマシンで実行する必要がありました。製品版で実行すると次のエラーが発生しました。

System.Windows.Markup.XamlParseException: ''指定されたバインディング制約に一致する型 'Microsoft.Toolkit.Wpf.UI.XamlHost.WindowsXamlHost' のコンストラクターの呼び出しで例外がスローされました。
Windows ランタイム型 'Windows.UI.Xaml.Hosting.WindowsXamlManager' が見つかりませんでした。

ただ、ここの説明を見ると Visual Studio のプレビュー版でプレビュー版の SDK をインストールするだけでよさそうです。 追記:Visual Studio のプレビュー版 & プレビュー版SDKをインストールしても変わりませんでした

■ コード等

WindowsFormsHost で WPF 上で WinForms コントロールを使う場合と同じ様に XAML 上でコントロールのプロパティなどを指定することはできませんでした。IsActive プロパティを設定するために WindowsXamlHost_ChildChanged イベントを使っています。
・コードビハインド

using System;
using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void WindowsXamlHost_ChildChanged(object sender, EventArgs e)
        {
            var host = (Microsoft.Toolkit.Wpf.UI.XamlHost.WindowsXamlHost)sender;
            var progressRing = (Windows.UI.Xaml.Controls.ProgressRing)host.Child;
            progressRing.IsActive = true;
        }
    }
}

・XAML

<Window x:Class="WpfApp1.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:WpfApp1"
        xmlns:xamlhost="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="400">
    <Grid>
        <xamlhost:WindowsXamlHost ChildChanged="WindowsXamlHost_ChildChanged"
                                  InitialTypeName="Windows.UI.Xaml.Controls.ProgressRing" />
    </Grid>
</Window>

■ 実行

f:id:rksoftware:20180930215340j:plain
ProgressRing を表示できました。実際のところ、ここまでして ProgressBar ではダメで ProgressRing でなければならない状況が想像できませんがいずれ役に立つ日が来るかもしれません。