雑記 |
Visual Basic 中学校 > 雑記 >
2022/10/9
この記事が対象とする製品・バージョン
Visual Studio 2022 | ◎ | 対象です。 | |
Visual Studio 2019 | ◎ | 対象です。 | |
Visual Studio 2017 | × | 対象外です。 | |
Visual Studio 2015 | × | 対象外です。 | |
Visual Studio 2013 | × | 対象外です。 | |
Visual Studio 2012 | × | 対象外です。 | |
Visual Studio 2010 | × | 対象外です。 | |
Visual Studio 2008 | × | 対象外です。 | |
Visual Studio 2005 | × | 対象外です。 | |
Visual Studio 2003 | × | 対象外です。 | |
Visual Studio (2002) | × | 対象外です。 | |
Visual Studio Code | × | 対象外です。 |
目次
.NETのアプリケーションで WPF の機能を使用する方法を説明します。
この記事では .NET 5 以上を対象にします。
コンソールアプリ や Windows フォームアプリ や ASP.NET Core Webアプリ など WPF以外のアプリケーションで WPF の機能が使用できるようになります。
この手順を実行すると、アプリケーションは Windows上でしか動作しなくなります。(WPFの機能はWindows上でしか実行できないため)
参考
Microsoft.NET.Sdk.Desktop の MSBuild プロパティ - .NET | Microsoft Learn
プロジェクトをダブルクリックして、TargetFramework に -windows を追加し、<UseWPF>true</UseWPF> を挿入すると WPF の機能を使用できるようになります。編集後に保存もお忘れなく。
たとえば、 <TargetFramework>net6.0</TargetFramework> となっている場合、<TargetFramework>net6.0-windows</TargetFramework> とします。
既に -windows が付いている場合は、不要です。
-windows以外の -xxxx が付いている場合(たとえば -ios 、- macos など)は、WPF を有効化できません。あきらめてください。(WPFはWindowsでしか動作しないため)。もし、Windowsでしか動作しなくなっても良いのであれば、-ios や - macos などを取り除いてその代わりに -windows を付けることで WPF を有効化することができます。
なお、私が何度か試したところ、変更直後に間髪入れずに実行するとエラーになることがありました。もう1度実行すると正常に実行できました。
通常、.NET では、既定ではない機能を使用するにはNuGetを使用するか、参照を使用しますが、WPFなど一部の機能は、この手順のように特別に用意された仕組みを使って有効化します。
次のC#のプログラムはWPFのMessageBoxクラスの機能を使って、画面にメッセージを表示します。
これを動作させるには、この記事で説明しているようにWPFの機能を有効化する必要があります。
System.Windows.MessageBox.Show("あいうえお");
(Windowsフォームアプリに慣れている方は、これが同じMessageBoxというクラスでもWindowsフォームアプリで使うMessageBoxではないことに注意してください。Windowsフォームアプリで使用するMessageBoxはSystem.Windows.Forms.MessageBoxです。)
この例の機能は特に魅力を感じませんが、WPFの機能を利用できれば、WPFが得意なグラフィック機能を使用してWebアプリで動的に画像を生成したりできるようになります(ただし、そのWebアプリはWindowsでしかホストできなくなるので、グラフィックが目的の場合 幅広く使える SkiaSharp から検討します)。もちろん、コンソールアプリやWindowsフォームアプリからWPFの機能を呼び出すこともできます。
使用する機能によっては この例外が発生することがあります。
解消するには、 Mainメソッドに [STAThread] 属性を付けます。(通常はmainですが、厳密にはアプリケーションのエントリーポイントであるメソッドです。)
たとえば、このプログラムはWPFのClipboardクラスの機能を使って文字列ABCをWindowsのクリップボードにコピーします。(マウスで文字を選択してコピーするのと同じ状態を作り出します。)
System.Windows.Clipboard.SetText("ABC");
コンソールアプリケーションでWPFを有効化しただけの状況でこの機能を呼び出すと、上記のエラーが発生します。
このエラーを解消するには Main メソッドに [STAThread]属性を適用します。通常コンソールアプリケーションでは Program.cs に Mainメソッドがあります。
internal class Program
{
[STAThread]
private static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
System.Windows.Clipboard.SetText("ABC");
}
}
Mainメソッド以外の場所に問題となる処理がある場合でも、Mainメソッドに STAThread属性を適用することで解消します。
なお、STAThread属性をつけても通常は副作用はありません。COMコンポーネント という機能を使用している場合には影響がある場合があります。COMコンポーネントを自分のプログラムから明示的に使用していない場合でも、何かの機能の内部でCOMコンポーネントが呼び出されている場合はあります。
コンソールアプリケーションなどでは「最上位レベルのステートメント」という機能により Main メソッドの定義が隠されている場合があります。
その場合、最上位レベルのステートメントを解除して、Mainメソッドを明示的に使用する方式に切り替えます。
その方法はこちらで説明しています。