WPF デスクトップ アプリを .NET 8 にアップグレードする方法

この記事では、Windows Presentation Foundation (WPF) デスクトップ アプリを .NET 8 にアップグレードする方法について説明します。 WPF がクロスプラットフォーム テクノロジである .NET 上で実行されるにもかかわらず、WPF は引き続き Windows 専用フレームワークです。 次の種類の WPF 関連プロジェクトを、.NET Upgrade Assistant を使用してアップグレードできます。

  • WPF プロジェクト
  • コントロール ライブラリ
  • .NET ライブラリ

.NET Framework から .NET にアップグレードする場合は、「WPF .NET との違い」の記事と、.NET Framework から .NET への移植に関するガイドを確認することを検討してください。

前提条件

デモ アプリ

この記事は、.NET サンプル GitHub リポジトリからダウンロードできる Web のお気に入りサンプル プロジェクトをアップグレードするというコンテキストで記載されました。

アップグレードを開始する

複数のプロジェクトをアップグレードする場合は、依存関係のないプロジェクトから始めます。 Web のお気に入りサンプルの WebSiteRatings プロジェクトは StarVoteControl ライブラリに依存しているため、StarVoteControl をまずアップグレードする必要があります。

ヒント

ソース管理やコピーなど、コードのバックアップを作成してください。

次の手順に従って Visual Studio でプロジェクトをアップグレードします。

  1. [ソリューション エクスプローラー] ウィンドウで StarVoteControl プロジェクトを右クリックし、[アップグレード] を選択します。

    The .NET Upgrade Assistant's Upgrade menu item in Visual Studio.

    新しいタブが開き、アップグレードの実行方法を選択するように求められます。

  2. [In-place project upgrade] (インプレースのプロジェクトのアップグレード) を選択します。

  3. 次に、ターゲット フレームワークを選択します。 アップグレードするプロジェクトの種類に基づいて、さまざまなオプションが表示されます。 .NET Standard 2.0 は、ライブラリが WPF などのデスクトップ テクノロジに依存せず、.NET Framework プロジェクトと .NET プロジェクトの両方で使用できる場合に適しています。 ただし、最新の .NET リリースでは、.NET Standard より多くの言語とコンパイラの改善が実現しています。

    [.NET 8.0] を選択し、[次へ] を選択します。

  4. コード ファイルやライブラリなど、プロジェクトに関連するすべての成果物を含むツリーが表示されます。 個々の成果物またはプロジェクト全体 (既定) をアップグレードできます。 [Upgrade selection] (アップグレードの選択) を選択して、アップグレードを開始します。

    アップグレードが完了すると、結果が表示されます。

    The .NET Upgrade Assistant's upgrade results tab, showing 7 out of the 21 items were skipped.

    緑で塗りつぶされた円が付された成果物はアップグレードされ、空の緑の円のものはスキップされました。 スキップされた成果物は、アップグレード アシスタントによってアップグレードする内容が見つからなかったものを意味します。

アプリのサポート ライブラリがアップグレードされたので、メインのアプリをアップグレードします。

アプリケーションのアップグレード

すべてのサポート ライブラリがアップグレードされたら、メインのアプリ プロジェクトをアップグレードできます。 次の手順を実行します:

  1. [ソリューション エクスプローラー] ウィンドウで WebSiteRatings プロジェクトを右クリックし、[アップグレード] を選択します。
  2. アップグレード モードとして [In-place project upgrade] (インプレースのプロジェクトのアップグレード) を選択します。
  3. ターゲット フレームワークとして [.NET 8.0] を選択し、[次へ] を選択します。
  4. すべての成果物を選択したままにして、[Upgrade selection] (アップグレードの選択) を選択します。

アップグレードが完了すると、結果が表示されます。 項目に警告記号がある場合は、読む対象のメモがあることを意味します。これは、項目を展開することで実行できます。

クリーン ビルドを生成する

プロジェクトがアップグレードされたら、それをクリーンしてコンパイルします。

  1. [ソリューション エクスプローラー] ウィンドウで WebSiteRatings プロジェクトを右クリックし、[クリーンする] を選択します。
  2. [ソリューション エクスプローラー] ウィンドウで WebSiteRatings プロジェクトを右クリックし、[ビルド] を選択します。

アプリケーションでエラーが発生した場合は、[Error List] (エラー一覧) ウィンドウで、推奨される修正方法と共にそれらを確認できます。

アップグレード後の手順

プロジェクトを .NET Framework から .NET にアップグレードする場合は、.「.NET Framework から .NET にアップグレードした後に最新化する」記事の情報を確認してください。

アップグレード後に、次の処理を行うことが考えられます。

  • NuGet パッケージを確認する。

    .NET Upgrade Assistant が、一部のパッケージを新しいバージョンにアップグレードしました。 この記事で提供されているサンプル アプリでは、Microsoft.Data.Sqlite NuGet パッケージが 1.0.0 から 8.0.x にアップグレードされました。 ただし、1.0.0SQLite NuGet パッケージに依存しますが、8.0.x はその依存関係を削除します。 SQLite NuGet パッケージはもう必要なくなりましたが、プロジェクトによって引き続き参照されます。 SQLiteSQLite.Native の両方の NuGet パッケージをプロジェクトから削除できます。

  • 古い NuGet パッケージをクリーンアップする。

    NuGet パッケージ参照がプロジェクト ファイルで宣言されたため、"packages.config" ファイルはもう必要なくなり、プロジェクトから削除できます。 また、Packages という名前のローカル NuGet パッケージ キャッシュ フォルダーが、プロジェクトのフォルダーまたは親フォルダーにあります。 このローカル キャッシュ フォルダーを削除できます。 新しい NuGet パッケージ参照は、".nuget\packages" という名前のユーザーのプロファイル ディレクトリで使用できるパッケージのグローバル キャッシュ フォルダーを使用します。

  • System.Configuration ライブラリを削除する。

    ほとんどの .NET Framework アプリは System.Configuration ライブラリを参照します。 アップグレード後も、このライブラリが引き続き直接参照されている可能性があります。

    System.Configuration ライブラリは、"app.config" ファイルを使用して、実行時の構成オプションをアプリに提供します。 .NET の場合、このライブラリは System.Configuration.ConfigurationManager NuGet パッケージに置き換えられました。 ライブラリへの参照を削除し、NuGet パッケージをプロジェクトに追加します。

  • アプリを最新化する箇所を確認する。

    .NET がリリースされて以来、API とライブラリは大きく変わりました。 ほとんどの場合、.NET Framework はこれらの機能強化にアクセスできません。 .NET にアップグレードすることで、最新のライブラリにアクセスできるようになりました。

    次のセクションでは、この記事で使用するサンプル アプリを最新化する領域について説明します。

最新化: Web ブラウザー コントロール

WPF サンプル アプリによって参照される WebBrowser コントロールは、Internet Explorer に基づいていて、時代遅れです。 .NET 用の WPF は、Microsoft Edge に基づく WebView2 コントロールを使用できます。 次の手順を実行して、新しい WebView2 Web ブラウザー コントロールにアップグレードします。

  1. Microsoft.Web.WebView2 NuGet パッケージを追加します。

  2. MainWindow.xaml ファイルで:

    1. ルート要素の wpfControls 名前空間にコントロールをインポートします。

      <mah:MetroWindow x:Class="WebSiteRatings.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:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
              xmlns:local="clr-namespace:WebSiteRatings"
              xmlns:vm="clr-namespace:WebSiteRatings.ViewModels"
              xmlns:VoteControl="clr-namespace:StarVoteControl;assembly=StarVoteControl"
              xmlns:wpfControls="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
              Loaded="MetroWindow_Loaded"
              mc:Ignorable="d"
              Title="My Sites" Height="650" Width="1000">
      
    2. <Border> 要素が宣言されている場所で、WebBrowser コントロールを削除し、wpfControls:WebView2 コントロールに置き換えます。

      <Border Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" BorderThickness="1" BorderBrush="Black" Margin="5">
          <wpfControls:WebView2 x:Name="browser" ScrollViewer.CanContentScroll="True" />
      </Border>
      
  3. MainWindow.xaml.cs 分離コード ファイルを編集します。 ListBox_SelectionChanged メソッドを更新して、browser.Source プロパティを有効な Uri に設定します。 このコードは以前、Web サイトの URL を文字列として渡していましたが、WebView2 コントロールは Uri を要求します。

    private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var siteCollection = (ViewModels.SiteCollection)DataContext;
    
        if (siteCollection.SelectedSite != null)
            browser.Source = new Uri(siteCollection.SelectedSite.Url);
        else
            browser.NavigateToString("<body></body>");
    }
    

アプリのユーザーが実行している Windows のバージョンに応じて、WebView2 ランタイムをインストールしなければならない場合があります。 詳細については、「WPF アプリでの WebView2 の使用を開始する」を参照してください。

最新化: appsettings.json

.NET Framework は、App.config ファイルを使用して、接続文字列やログ プロバイダーなどのアプリの設定を読み込みます。 .NET は、アプリ設定に appsettings.json ファイルを使用するようになりました。 App.config ファイルは、System.Configuration.ConfigurationManager NuGet パッケージを通して .NET でサポートされます。また、appsettings.json のサポートは、Microsoft.Extensions.Configuration NuGet パッケージによって提供されます。

他のライブラリが .NET にアップグレードする際には、App.config ではなく、appsettings.json をサポートすることで最新化を行っています。たとえば、.NET 6 以上用にアップグレードされた .NET Framework のログ プロバイダーは、設定に App.config をもはや使用していません。 この方向に従うことと、可能な場合は App.config の使用を停止することもお勧めします。

WPF サンプル アプリで appsettings.json を使用する

例えば、WPF サンプル アプリをアップグレードした後、ローカル データベースに対する接続文字列用に appsettings.json を使用します。

  1. System.Configuration.ConfigurationManager NuGet パッケージを削除します。

  2. Microsoft.Extensions.Configuration.Json NuGet パッケージを追加します。

  3. appsettings.json という名前のファイルをプロジェクトに追加します。

  4. 出力ディレクトリにコピーする appsettings.json ファイルを設定します。

    ソリューション エクスプローラーでファイルを選択後、[プロパティ] ウィンドウを使用して、Visual Studio 経由で出力にコピー設定を行います。 別の方法として、プロジェクトを直接編集し、次の ItemGroup を追加することもできます。

      <ItemGroup>
        <Content Include="appsettings.json">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Content>
      </ItemGroup>
    
  5. App.config ファイルの設定を新しい appsettings.json ファイルに移行します。

    WPF サンプル アプリでは、app.config には 1 つの接続文字列のみが含まれていました。 appsettings.json ファイルを編集して、次のように接続文字列を定義します。

    {
      "ConnectionStrings": {
        "database": "DataSource=sqlite.db;"
      }
    }
    
  6. App.xaml.cs ファイルを編集して、appsettings.json ファイルを読み込む構成オブジェクトをインスタンス化すると、追加された行が強調表示されます。

    using System.Windows;
    using Microsoft.Extensions.Configuration;
    
    namespace WebSiteRatings
    {
        /// <summary>
        /// Interaction logic for App.xaml
        /// </summary>
        public partial class App : Application
        {
            public static IConfiguration Config { get; private set; }
    
            public App()
            {
                Config = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.json")
                    .Build();
            }
        }
    }
    
  7. .\Models\Database.cs ファイルで、新しい App.Config プロパティを使用するように OpenConnection メソッドを変更します。 これには、Microsoft.Extensions.Configuration 名前空間をインポートする必要があります。

    using Microsoft.Data.Sqlite;
    using System.Collections.Generic;
    using Microsoft.Extensions.Configuration;
    
    namespace WebSiteRatings.Models
    {
        internal class Database
        {
            public static SqliteConnection OpenConnection() =>
                new SqliteConnection(App.Config.GetConnectionString("database"));
    
            public static IEnumerable<Site> ReadSites()
    

    GetConnectionString は、Microsoft.Extensions.Configuration 名前空間によって提供される拡張メソッドです。