rksoftware

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

秋葉原 C# もくもく会 #57 勉強会を開催しました

■ C# もくもく会

C# もくもく会 #57 を開催しました。

C# もくもく会 は東京の秋葉原で毎週木曜日に開催している .NET 系の勉強会です。
もくもく自習を基本とし、分からないことを教えあったり情報共有したりしている会です。 定期開催していますので、お時間のある時に遊びに来ていただければと思います。
ちょっと詰まった時、ネット上で聞くのははずかしいなぁ、という課題のできた時などにも思い出していただけると嬉しいです。

f:id:rksoftware:20181006141919j:plain

■ 今週の成果発表

今週は、Visual Studio のアップデートの確認や Alexa skill、.NET Core 3.0 で Windows デスクトップなどをやってみたなどの話がありました。

ちなみに本会ですが、実は公序良俗に反しなければどのような技術を扱っても大丈夫です。そもそも C# エンジニアが C# だけしか使わないというわけではありませんし。

■初心者歓迎

このもくもく会には、入門者の方も多くご参加いただいています。 突然 C# やらなければならなくなって途方に暮れている方、何となく C# をやってきたけど改めて見直してみたい方なども大歓迎です。
入門セミナー代わりでのご参加も歓迎です。プログラミング入門者の方も是非遊びに来てください。

特に C# で課題をお持ちでなくても是非遊びに来てください。

■ 目指す勉強会スタイル

世界一敷居の低い勉強会を目指しています。

何か聞きたいことがある場合は、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

何か共有したい情報を見つけた場合も、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

そんなスタイルでやっています。

■ 次回予定

次回は 2018/10/11 に開催予定です。

C# に関心のある方、是非遊びに来てください。

Visual Studio の 15.8.6 がリリースされました

Visual Studio のアップデート 15.8.6 がリリースされました。

今回は日本語が公開されています。修正された主な問題の機械翻訳っぽさがたまらないですね。

更新内容

  • Windows 10 SDK (10.0.17763.0) がインストールできるようになりました。

バグ修正
更新内容の引用です。

・Intellisense の NuGet パッケージが破損しているします。
・Visual Studio を sln を開いた後閉じますします。
・15.8.4 内でも固定 App.Config XML エディターします。

とりあえず語尾に「します。」が付くのが良いですね。それぞれ

  • NuGet で追加したパッケージ内のクラスがインテリセンスで出てこない? らしい
  • 2016バージョンの sln を 2017 で開くと数秒でエラー表示もなく Visual Studio が閉じる らしい
  • WCF のサービスとクライアントの App.config を編集していると Visual Studio がフリーズする らしい

という問題が解消したそうです。 重大な問題が解消しています。さらにアップデート内容の Windows 10 SDK (10.0.17763.0) が魅力ですね。そくアップデートしましょう。

■ 更新方法

Visual Studio の更新はメニューの ツール > ツールと機能を取得 で開くインストーラーから行えます。

WPF で ProgressBar が動かない

「ProgressBar IsIndeterminate 動かない」という検索ワードでこのブログへたどり着く方がいらっしゃるようで、こういうことなのかは分かりませんがちょっと書いておこうと思います。
まずは WPF で ProgressBar を使う方法の記事です。

■ IsIndeterminate = true にしても動かない

次のコードでは、「ProgressBar は動きません

<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"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="300">
    <StackPanel VerticalAlignment="Center">
        <ProgressBar x:Name="progressBar" IsIndeterminate="False" Height="10"/>
        <Button Content="Button" Click="Button_Click"/>
    </StackPanel>
</Window>
using System.Windows;

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

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            progressBar.IsIndeterminate = true;
            // 10 秒かかる処理
            System.Threading.Thread.Sleep(10 * 1000);
            progressBar.IsIndeterminate = false;
        }
    }
}

ボタンクリックのイベントハンドラで、progressBar.IsIndeterminate = true; とした後に時間のかかる処理をしていますが残念ながら動きません。原因はボタンのイベントハンドラが UI スレッドで動作しているためです。UI スレッドで重い処理をしているので UI がブロックされて、画面表示の更新もブロックされしまいます。いわゆる「応答していません」状態になっています。

■ 動くようにする

using System.Windows;

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

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            progressBar.IsIndeterminate = true;
            // 10 秒かかる処理
            await System.Threading.Tasks.Task.Delay(10 * 1000);
            progressBar.IsIndeterminate = false;
        }
    }
}

イベントハンドラを async にし重い処理も async にします。こうすることで重い処理がバックグラウンドのスレッドで行われるようになり、UI が更新されるようになります。
※注意: UI がブロックされなくなったことで、重い処理中に画面の操作ができるようになってしまいます。例えばボタンを連打するなどが可能になってしまいます。重い処理中は画面のコントロールをすべて無効化するなどの対策も必要になります。

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 でなければならない状況が想像できませんがいずれ役に立つ日が来るかもしれません。

.NET Core 3.0 でデスクトップアプリを作る(VS プレビュー版を使わない)

以前 .NET Core 3.0 で WPF や WinForms のデスクトップアプリが作れるようになるという発表があり、クラシックデスクトップアプリ界隈が非常に高い関心を示しています。そんな .NET Core 3.0 でデスクトップアプリですが、実際に試せるそうです。 単純に試すだけならこの非常に素晴らしいブログ記事の通りなのですが、私にはこの記事通りにいかない悲しい事情がありました。ディスク容量の問題で Visual Studio のプレビュー版をインストールすることが難しかったのです。

■ コマンドで頑張る

ということで、この記事では Visual Studio のプレビュー版をインストールせずに頑張ってみます。
前半部分は前述の記事をほぼなぞった内容ですので、読み飛ばしてもOKです。

.NET Core をインストール

前述の記事を参考に .NET Core 3.0 をインストールします。インストール後、次のコマンドでバージョンを確認します。

> dotnet --version
3.0.100-alpha1-009622

この記事を書いている時点では 3.0.100-alpha1-009622 というバージョンでした。

プロジェクトの作成

次のコマンドでプロジェクトを作成します。ここでは -n オプションを指定し wpfapp という名前でプロジェクトを作成しています。

> dotnet new wpf -n wpfapp
テンプレート "WPF Application" が正常に作成されました。

プロジェクトのフォルダが生成されるのでフォルダを移動します。

> cd wpfapp

dotnet コマンドでビルドを試みる(失敗)

dotnet コマンドでビルドを試みてみます。

> dotnet build

次のエラーが表示され失敗します。

WPF projects cannot currently be built with .NET Core MSBuild.  
Try running 'msbuild' instead of a 'dotnet' command (such as 'dotnet msbuild')

ちなみに VSCode でプロジェクトを開いてデバッグしようとしても、当然と言えば当然ですが同じ結果になりました。

MSBuild でビルドを試みる(成功)

※MSBuild はインストールしている Visual Studio のエディションによりパスが異なると思います。

> "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe"

ビルドに成功しました。Visual Studio 製品版のものでOKでした。
ちなみに製品版の Visual Studio で開いてビルド等しようとすると、.netcore3.0 は対応していない、といった内容のエラーになります。

実行

ようやく実行です。次のコマンドで実行できます。

> dotnet bin\Debug\netcoreapp3.0\wpfapp.dll

f:id:rksoftware:20180930210206j:plain
見事実行できました!

mac で実行(失敗)

.NET Core 3.0 でデスクトップアプリの報に対して多くの方が WPF などがクロスプラットフォームになるのかと期待したと思います。しかし残念ながら動作環境は Windows だけです。ですがとりあえず mac でもコマンドを打ってみましたしてみました。

> dotnet wpfapp.dll 
It was not possible to find any compatible framework version
The specified framework 'Microsoft.DesktopUI.App', version '3.0.0-alpha-26921-3' was not found.

当然ではありますが動きませんでした。残念。

秋葉原 C# もくもく会 #56 勉強会を開催しました

■ C# もくもく会

C# もくもく会 #56 を開催しました。

C# もくもく会 は東京の秋葉原で毎週木曜日に開催している .NET 系の勉強会です。
もくもく自習を基本とし、分からないことを教えあったり情報共有したりしている会です。 定期開催していますので、お時間のある時に遊びに来ていただければと思います。
ちょっと詰まった時、ネット上で聞くのははずかしいなぁ、という課題のできた時などにも思い出していただけると嬉しいです。

■ 今週の成果発表

今週は、.NET Core 3 や WindowsXamlHost、ASP.NET MVC などをやってみたなどの話がありました。

ちなみに本会ですが、実は公序良俗に反しなければどのような技術を扱っても大丈夫です。そもそも C# エンジニアが C# だけしか使わないというわけではありませんし。

■初心者歓迎

このもくもく会には、入門者の方も多くご参加いただいています。 突然 C# やらなければならなくなって途方に暮れている方、何となく C# をやってきたけど改めて見直してみたい方なども大歓迎です。
入門セミナー代わりでのご参加も歓迎です。プログラミング入門者の方も是非遊びに来てください。

特に C# で課題をお持ちでなくても是非遊びに来てください。

■ 目指す勉強会スタイル

世界一敷居の低い勉強会を目指しています。

何か聞きたいことがある場合は、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

何か共有したい情報を見つけた場合も、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

そんなスタイルでやっています。

■ 次回予定

次回は 2018/10/04 に開催予定です。

C# に関心のある方、是非遊びに来てください。

UWP で ProgressRing

以前に UWP で ProgressBar で処理中を表現する記事を書きました。

しかし、モバイルOSの世界では一般的に Ring 表現ですし、Webサイトでも Ring 表現が多くなっています。

という感じに最近はやりの ProgressRing ですが実は UWP の標準コントロールにもあります。

■ XAML

<Page
    x:Class="App.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <ProgressRing IsActive="True"
                      HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
    </Grid>
</Page>

■ 表示

f:id:rksoftware:20180927025754j:plain

■ 解説

これだけで ProgressRing を表示できました。

まさにそのままの名前の ProgressRing コントロールを置いて、IsActive プロパティに True を設定すれば OK です。IsActive プロパティが False の場合表示されません。デフォルトが False なので注意してください。