「Avalonia UI - ダイアログ」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
 
(同じ利用者による、間の16版が非表示)
21行目: 21行目:
<br>
<br>
ダイアログの結果の処理において、ユーザの選択や入力に基づいて、適切なアクションを実行するようにコードを設計する必要がある。<br>
ダイアログの結果の処理において、ユーザの選択や入力に基づいて、適切なアクションを実行するようにコードを設計する必要がある。<br>
<br><br>
== MsBox.Avaloniaライブラリ ==
==== MsBox.Avaloniaライブラリとは ====
MsBox.Avaloniaは、Avalonia UIフレームワーク用のメッセージボックスライブラリである。<br>
このライブラリを使用することにより、開発者はAvalonia UIアプリケーションに洗練されたカスタマイズ可能なメッセージボックスを簡単に実装できる。<br>
<br>
MsBox.Avaloniaの主な特徴として、高度なカスタマイズ性が挙げられる。<br>
開発者はメッセージボックスのタイトル、本文、ボタン、アイコンなどを自由に設定することができる。<br>
また、表示するボタンの種類や配置も柔軟に変更可能であり、アプリケーションの要件に合わせて調整できる。<br>
<br>
シンプルなAPIを提供しており、数行のコードでメッセージボックスを表示することができる。<br>
非同期操作にも対応しているため、モダンなC#プログラミングの流れに沿った実装が可能である。<br>
<br>
デザイン面では、Avalonia UIの美しさを損なうことなく、アプリケーションの全体的な外観と調和するメッセージボックスを定義できる。<br>
さらに、ダークモード、ライトモード等の異なるテーマにも対応している。<br>
<br>
MsBox.Avaloniaは、単純な情報表示からユーザの確認や選択を求める複雑な対話まで、様々な用途に適している。<br>
例えば、操作の確認、エラー通知、警告メッセージの表示等に使用できる。<br>
<br>
MsBox.Avaloniaは、NuGetパッケージマネージャーを通じて簡単にプロジェクトに追加できるため、必要な名前空間をインポートするだけですぐに使用を開始することができる。<br>
<br>
<u>MsBox.Avaloniaライブラリは、MITライセンスに準拠している。</u><br>
<br>
* MsBox.AvaloniaのGithub
*: https://github.com/AvaloniaCommunity/MessageBox.Avalonia
<br>
==== MsBox.Avaloniaライブラリのインストール ====
RiderまたはVisual StudioからNuGetを使用して、MsBox.Avaloniaライブラリをインストールする。<br>
* Riderの場合
*# プロジェクトを開く。
*# [ツール]メインメニュー - [Nuget] - [ソリューション の Nuget パッケージを管理] (または、[<プロジェクト名> の Nuget パッケージを管理])を選択する。
*# メイン画面下部にある[パッケージ]タブから <u>MsBox.Avalonia</u> と入力して検索する。
*# メイン画面下部の右にある[+]ボタンを押下して、MsBox.Avaloniaライブラリをインストールする。
*: <br>
* Visual Studioの場合
*# プロジェクトを開く。
*# NuGetパッケージマネージャーを開く。
*#* [ツール]メインメニュー - [NuGetパッケージマネージャー]を選択して、[ソリューションのNuGetパッケージの管理]を選択する。
*#* または、ソリューションエクスプローラーでプロジェクトを右クリックして、コンテキストメニューから[NuGetパッケージの管理]を選択する。
*# MsBox.Avaloniaライブラリを検索する。
*#: NuGetパッケージマネージャーの検索ボックスに <u>MsBox.Avalonia</u> と入力して検索する。
*# MsBox.Avaloniaライブラリのインストール
*#: 検索結果からMsBox.Avaloniaライブラリを選択して、[インストール]ボタンを押下する。
*# インストールの確認ダイアログが表示されるので、[OK]ボタンを押下してインストールを完了する。
*# 参照の確認
*#: インストールが完了した後、プロジェクトの参照にMsBox.Avaloniaライブラリが追加されていることを確認する。
*: <br>
* パッケージマネージャーコンソールからインストールする場合
*# プロジェクトを開く。
*# [表示]メインメニュー - [その他のウィンドウ] - [パッケージマネージャーコンソール]を選択して、パッケージマネージャーコンソールを開く。
*# パッケージマネージャーコンソールから、MsBox.Avaloniaライブラリをダウンロードしてインストールする。
*#: <code>Install-Package MsBox.Avalonia</code>
*# ソリューションエクスプローラーのプロジェクトの参照において、MsBox.Avaloniaライブラリが追加されていることを確認する。
*: <br>
* <code>dotnet</code>コマンドを使用する場合
*# ターミナルを開く。
*# プロジェクトのルートディレクトリに移動する。
*# MsBox.Avaloniaライブラリをインストールする。
*#: 最新の安定版をインストールする場合
*#: <code>dotnet add package MsBox.Avalonia</code>
*#: <br>
*#: バージョンを指定してインストールする場合
*#: <code>dotnet add package MsBox.Avalonia --version <バージョン></code>
*#: <br>
*: <u>※注意</u>
*: <u>プロジェクトがGit等のバージョン管理システムを使用している場合、これらの変更がトラッキングされることを確認すること。</u>
*: <u>プロジェクトを再ビルドして、新しく追加されたパッケージが正しく統合されていることを確認することを推奨する。</u>
<br>
プロジェクトにおいて、MsBox.Avaloniaライブラリを使用する場合は、ソースコードファイルの先頭にusingステートメントを追加する。<br>
<syntaxhighlight lang="c#">
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
</syntaxhighlight>
<br>
==== メッセージボックスの表示 ====
MessageBoxManager.GetMessageBoxStandardメソッドを実行して、メッセージボックスを定義する。<br>
タイトル、メッセージ、ボタンの種類、アイコンを指定することができる。<br>
<br>
ShowAsyncメソッドを実行して、メッセージボックスを非同期で表示する。<br>
<br>
<syntaxhighlight lang="c#">
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
public partial class MainWindow : Window
{
    public MainWindow()
    {
      InitializeComponent();
    }
    private void InitializeComponent()
    {
      AvaloniaXamlLoader.Load(this);
    }
    public async void ShowMessageBox(object sender, RoutedEventArgs e)
    {
      var messageBoxStandardWindow = MessageBoxManager.GetMessageBoxStandard("<タイトル>",
                                                                              "<メッセージボックスの本文>",
                                                                              ButtonEnum.OkCancel,
                                                                              Icon.Info);
      // メッセージボックスを表示
      var result = await messageBoxStandardWindow.ShowAsync();
      if (result == ButtonResult.Ok)
      {  // OKボタンが押下された場合
          await MessageBoxManager.GetMessageBoxStandard("結果", "OKボタンが押下された").ShowAsync();
      }
      else
      {
          // Cancelボタンが押下された場合
          await MessageBoxManager.GetMessageBoxStandard("結果", "キャンセルボタンが押下された").ShowAsync();
      }
    }
}
</syntaxhighlight>
<br><br>
<br><br>


316行目: 194行目:
| AllowMultiple || bool || 複数のアイテムの選択を許可するかどうかを指定する。<br>複数のアイテムを選択する場合 : true<br>単一のファイルのみの場合 : false (既定値 : false)
| AllowMultiple || bool || 複数のアイテムの選択を許可するかどうかを指定する。<br>複数のアイテムを選択する場合 : true<br>単一のファイルのみの場合 : false (既定値 : false)
|-
|-
| FileTypeFilter || IReadOnlyList<FilePickerFileType>型 || <code>FilePickerOpenOptions</code>等のオプションクラスのプロパティとして使用する。<br>選択可能なファイルタイプを制限するためのフィルタのリストを指定する。
| FileTypeFilter<br><br>(厳密にはプロパティではない) || IReadOnlyList<FilePickerFileType>型 || <code>FilePickerOpenOptions</code>等のオプションクラスのプロパティとして使用する。<br>選択可能なファイルタイプを制限するためのフィルタのリストを指定する。
|-
|-
| SuggestedStartLocation || IStorageFolder型 || ファイルピッカーやフォルダピッカーが開く初期ディレクトリを指定する。<br><code>FilePickerOpenOptions</code>や<code>FolderPickerOpenOptions</code>等のオプションクラスのプロパティとして使用する。<br><br>未指定または<code>null</code>を指定した場合、ファイルピッカーやフォルダピッカーは、システムやアプリケーションのデフォルトの開始位置を使用する。<br>多くの場合、ユーザのドキュメントディレクトリ、または、最後にファイルピッカーを使用した場所になる。
| SuggestedStartLocation<br><br>(厳密にはプロパティではない) || IStorageFolder型 || ファイルピッカーやフォルダピッカーが開く初期ディレクトリを指定する。<br><code>FilePickerOpenOptions</code>や<code>FolderPickerOpenOptions</code>等のオプションクラスのプロパティとして使用する。<br><br>未指定または<code>null</code>を指定した場合、ファイルピッカーやフォルダピッカーは、システムやアプリケーションのデフォルトの開始位置を使用する。<br>多くの場合、ユーザのドキュメントディレクトリ、または、最後にファイルピッカーを使用した場所になる。
|-
|-
| Title || string || ファイル選択ダイアログのウインドウタイトルを指定する。
| Title || string || ファイル選択ダイアログのウインドウタイトルを指定する。
324行目: 202行目:
</center>
</center>
<br>
<br>
<br>
 
==== Filtersプロパティ (ファイルの種類) の設定 ====
==== FileTypeFilter (ファイルの種類) の設定 ====
ダイアログで開くことができるファイルの種類は、<code>Filters</code>プロパティにフィルタ文字列を設定する。<br>
ダイアログで開くことができるファイルの種類は、<code>FilePickerOpenOptions</code>クラスの<code>FileTypeFilter</code>プロパティにフィルタ文字列を設定する。<br>
<br>
<br>
フィルタ文字列の設定を以下に示す。<br>
フィルタ文字列の設定を以下に示す。<br>
* FileDialogFilterクラスの使用
* FilePickerOpenOptionsクラス (オプションクラス) の使用
*: 各フィルタはFileDialogFilterオブジェクトとして定義される。
*: FilePickerOpenOptionsクラスのインスタンスを作成し、そのFileTypeFilterプロパティにフィルタを設定する。
* Nameプロパティ
*: <br>
*: ユーザに表示されるフィルタの名前。
* FilePickerFileTypeクラスの使用
* Extensionsプロパティ
*: 各フィルタはFilePickerFileTypeオブジェクトとして定義されます。コンストラクタの引数にフィルタの名前を指定する。
*: 拡張子のリストであり、ワイルドカード (*) を含めずに指定する。
*: <br>
* Patterns
*: Patternsプロパティに、フィルタに含める拡張子のパターンを指定する。
*: <br>
* 複数の拡張子
* 複数の拡張子
*: 1つのフィルタに複数の拡張子を含めることができる。
*: 1つのフィルタに複数の拡張子を含めることができる。
*: 例えば、"HTMLファイル"フィルタでは、"*.html" と "*.htm" の両方を指定する。
*: <br>
* 全てのファイル
* 全てのファイル
*: 全てのファイルを表す場合は、拡張子として <code>"*"</code> を使用する。
*: 全てのファイルを表す場合は、拡張子として "*" を使用する。
*: 例えば、"すべてのファイル"フィルタがこれに該当する。
*: <br>
* フィルタの順序
* フィルタの順序
*: リストに追加した順序でユーザに表示される。
*: リストに追加した順序でユーザに表示される。
*: 以下の例では、"すべてのファイル"が最初に表示されて、以降"テキストファイル"、"XMLファイル"等の順で表示される。
<br>
この設定により、ユーザは様々なファイルタイプから選択できる。<br>
特定のファイル形式に絞り込む場合や全てのファイルを表示することもできる。<br>
<br>
<br>
<br>
  <syntaxhighlight lang="c#">
  <syntaxhighlight lang="c#">
  using Avalonia.Controls;
  var storageProvider = TopLevel.GetTopLevel(this)?.StorageProvider;
using System.Collections.Generic;
   
   
  public class FileDialogExample
  var options = new FilePickerOpenOptions
  {
  {
     public void ShowFileDialog()
     FileTypeFilter = new[]
     {
     {
       var dialog = new OpenFileDialog();
       new FilePickerFileType("すべてのファイル") { Patterns = new[] { "*" } },
      new FilePickerFileType("テキストファイル") { Patterns = new[] { "*.txt" } },
      new FilePickerFileType("XMLファイル")    { Patterns = new[] { "*.xml" } },
      new FilePickerFileType("HTMLファイル")   { Patterns = new[] { "*.html", "*.htm" } },
      new FilePickerFileType("Webファイル")    { Patterns = new[] { "*.html", "*.htm", "*.css", "*.js" } },
      new FilePickerFileType("XMLファイルとHTMLファイル") { Patterns = new[] { "*.xml", "*.html", "*.htm" } },
      new FilePickerFileType("イメージファイル") { Patterns = new[] { "*.png", "*.jpg", "*.gif", "*.bmp", "*.webp" } }
    }
};
   
   
      // Filtersプロパティの設定方法 1
  var file = await storageProvider.OpenFilePickerAsync(options);
      // List<FileDialogFilter>の使用
      dialog.Filters = new List<FileDialogFilter>
      {
          new FileDialogFilter { Name = "すべてのファイル", Extensions = new List<string> { "*" } },
          new FileDialogFilter { Name = "テキストファイル", Extensions = new List<string> { "txt" } },
          new FileDialogFilter { Name = "テキストファイルとすべてのファイル", Extensions = new List<string> { "txt", "*" } },
          new FileDialogFilter { Name = "XMLファイル", Extensions = new List<string> { "xml" } },
          new FileDialogFilter { Name = "HTMLファイル", Extensions = new List<string> { "html", "htm" } },
          new FileDialogFilter { Name = "XMLファイルとHTMLファイルとすべてのファイル", Extensions = new List<string> { "xml", "html", "htm", "*" } },
          new FileDialogFilter { Name = "イメージファイル", Extensions = new List<string> { "png", "jpg", "gif", "bmp" } }
      };
   
      // Filtersプロパティの設定方法 2
      // FiltersのAddメソッドの使用
      dialog.Filters.Add(new FileDialogFilter { Name = "すべてのファイル", Extensions = { "*" } });
      dialog.Filters.Add(new FileDialogFilter { Name = "テキストファイル", Extensions = { "txt" } });
      dialog.Filters.Add(new FileDialogFilter { Name = "テキストファイルとすべてのファイル", Extensions = new List<string> { "txt", "*" } });
      dialog.Filters.Add(new FileDialogFilter { Name = "XMLファイル", Extensions = { "xml" } });
      dialog.Filters.Add(new FileDialogFilter { Name = "HTMLファイル", Extensions = new List<string> { "html", "htm" } });
      dialog.Filters.Add(new FileDialogFilter { Name = "XMLファイルとHTMLファイルとすべてのファイル", Extensions = new List<string> { "xml", "html", "htm", "*" } });
      dialog.Filters.Add(new FileDialogFilter { Name = "イメージファイル", Extensions = new List<string> { "png", "jpg", "gif", "bmp" } });
      // ファイル選択ダイアログを表示
      var result = await dialog.ShowAsync(this);
      if (result != null)
      {
          foreach (var path in result)
          {
            System.Console.WriteLine($"Selected file: {path}");
          }
      }
    }
}
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== 使用例 ====
==== 使用例 ====
以下の例では、FilePickerOpenOptionsクラスを使用してstorageProviderクラスを設定した後、ディレクトリ選択ダイアログを開いている。<br>
以下の例では、FilePickerOpenOptionsクラスを使用してstorageProviderクラスを設定した後、ディレクトリ選択ダイアログを開いている。<br>
555行目: 420行目:
  using System.Threading.Tasks;
  using System.Threading.Tasks;
   
   
  namespace AvaloniaFileSaveDialog
  public partial class MainWindow : Window
  {
  {
     public partial class MainWindow : Window
     public MainWindow()
    {
      InitializeComponent();
    }
    private void InitializeComponent()
    {
      AvaloniaXamlLoader.Load(this);
    }
    // 保存ボタンを押下
    public async void OnSaveButtonClicked(object sender, RoutedEventArgs e)
     {
     {
       public MainWindow()
       try
       {
       {
           InitializeComponent();
           string content = "Hello, directory.";  // 保存する内容
          string savedFilePath = await ShowSaveFileDialogAsync();
          if (!string.IsNullOrEmpty(savedFilePath))
          {
            await SaveFileAsync(savedFilePath, content);
            Console.WriteLine("成功", $"ファイルを正常に保存: {savedFilePath}");
          }
       }
       }
       catch (Exception ex)
       private void InitializeComponent()
       {
       {
           AvaloniaXamlLoader.Load(this);
           Console.WriteLine("エラー", $"ファイルの保存中にエラーが発生: {ex.Message}");
       }
       }
    }
    // ファイル保存ダイアログを表示して、選択されたファイルパスを返す
    private async Task<string> ShowSaveFileDialogAsync()
    {
      var saveFileDialog = new SaveFileDialog();
      // ダイアログのタイトル
      saveFileDialog.Title = "ファイルを保存";
      // .txtファイルのフィルタを追加
      saveFileDialog.Filters.Add(new FileDialogFilter { Name = "テキストファイル", Extensions = { "txt" } });
      string result = await saveFileDialog.ShowAsync(this);
      return result;
    }
    // 指定されたパスにファイルを非同期で保存
    private async Task SaveFileAsync(string filePath, string content)
    {
      await File.WriteAllTextAsync(filePath, content);
    }
}
</syntaxhighlight>
<br><br>
== ディレクトリ選択タイアログ ==
==== OpenFolderDialogクラスのプロパティ ====
下表に、ディレクトリ選択ダイアログのプロパティのうち、設定を意識する必要がある主なプロパティを示す。<br>
<br>
<center>表. OpenFolderDialogクラスの主なプロパティ<br>
{| class="wikitable" style="background-color:#fefefe;"
|-
! style="background-color:#00ffff;" | プロパティ名
! style="background-color:#00ffff;" | データ型
! style="background-color:#00ffff;" | 意味
|-
| AllowMultiple || bool || 複数のアイテムの選択を許可するかどうかを指定する。<br>複数のアイテムを選択する場合 : true<br>単一のファイルのみの場合 : false (既定値 : false)
|-
| Directory || string || ダイアログが最初に開くディレクトリのパスを指定する。<br>ユーザが頻繁にアクセスするディレクトリやアプリケーションのデフォルトディレクトリを初期表示するために使用する。<br><br>例: "ドキュメント"ディレクトリを初期ディレクトリとして指定する場合<br><code>Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)</code>
|-
| SuggestedStartLocation || IStorageFolder型 || ダイアログの推奨される開始位置を指定する。<br><code>Directory</code>プロパティの代替として使用できる。<br>特定のストレージプロバイダ (例: OneDriveディレクトリ) を初期位置として指定する場合に特に有効である。<br><br><u>※注意</u><br><u>この値が設定されている場合、Directoryプロパティよりも優先される。</u>
|-
| Title || string || ディレクトリ選択ダイアログのウインドウタイトルを指定する。
|}
</center>
<br>
==== 使用例 ====
以下の例では、Avalonia UIを使用してディレクトリ選択ダイアログを使用している。<br>
<br>
ダイアログはユーザのデスクトップディレクトリから開始されるが、何らかの理由でデスクトップディレクトリにアクセスできない場合は、ドキュメントディレクトリにフォールバックする。<br>
<br>
この方法は、ユーザが頻繁に使用するディレクトリからダイアログを開始することにより、ユーザエクスペリエンスを向上させることができる。<br>
また、<code>SuggestedStartLocation</code>プロパティを使用することで、将来的により柔軟な開始位置の設定 (例: アプリケーション固有のストレージフォルダ等) が可能になる。<br>
<br>
<syntaxhighlight lang="c#">
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using System;
using System.Threading.Tasks;
public partial class MainWindow : Window
{
    public MainWindow()
    {
      InitializeComponent();
    }
   
   
      // 保存ボタンを押下
    // ディレクトリ選択ボタンのクリックイベントハンドラ
      public async void OnSaveButtonClicked(object sender, RoutedEventArgs e)
    private async void OnSelectDirectoryClicked(object sender, RoutedEventArgs e)
    {
      try
       {
       {
           try
           // OpenFolderDialogのインスタンスを生成
          var dialog = new OpenFolderDialog
           {
           {
             string content = "これはファイルの内容です";  // 保存する内容
             // ダイアログのタイトルを設定
             string savedFilePath = await ShowSaveFileDialogAsync();
             Title = "ディレクトリを選択してください",
   
   
             if (!string.IsNullOrEmpty(savedFilePath))
             // 初期ディレクトリを設定
            {
            Directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
                await SaveFileAsync(savedFilePath, content);
          };
                Console.WriteLine("成功", $"ファイルを正常に保存: {savedFilePath}");
             }
          // SuggestedStartLocationを設定
          // デスクトップディレクトリを推奨開始位置として使用
          var desktopFolder = await StorageProvider.TryGetFolderFromPathAsync(
                                      Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
          if (desktopFolder != null)
          {
             dialog.SuggestedStartLocation = desktopFolder;
           }
           }
           catch (Exception ex)
           else
           {
           { // デスクトップフォルダが取得できない場合は、従来のDirectoryプロパティを使用
             Console.WriteLine("エラー", $"ファイルの保存中にエラーが発生: {ex.Message}");
             dialog.Directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
           }
           }
      }
      // ファイル保存ダイアログを表示して、選択されたファイルパスを返す
      private async Task<string> ShowSaveFileDialogAsync()
      {
          var saveFileDialog = new SaveFileDialog();
   
   
           // ダイアログのタイトル
           // ダイアログを表示して、ディレクトリを選択するまで待機
           saveFileDialog.Title = "ファイルを保存";
           string? result = await dialog.ShowAsync(this);
   
   
           // .txtファイルのフィルタを追加
           // 結果の処理
           saveFileDialog.Filters.Add(new FileDialogFilter { Name = "テキストファイル", Extensions = { "txt" } });
          if (result != null)
   
           {  // 選択されたディレクトリパスを表示
          string result = await saveFileDialog.ShowAsync(this);
            Console.WriteLine($"{result}");
           return result;
          }
          else
          { // ユーザがキャンセルした場合やディレクトリが選択されなかった場合
            Console.WriteLine("ディレクトリが未選択");
           }
       }
       }
       catch (Exception ex)
      // 指定されたパスにファイルを非同期で保存
       { // 予期せぬエラーが発生した場合
       private async Task SaveFileAsync(string filePath, string content)
           Console.WriteLine($"エラーが発生: {ex.Message}");
       {
           await File.WriteAllTextAsync(filePath, content);
       }
       }
     }
     }
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>  
<br><br>
<br><br>


== ディレクトリ選択タイアログ (StorageProviderクラス) ==
== ディレクトリ選択タイアログ (StorageProviderクラス) ==
==== StorageProviderクラスのプロパティ ====
==== StorageProviderクラスのプロパティ ====
下表に、ファイル選択ダイアログのプロパティのうち、設定を意識する必要がある主なプロパティを示す。<br>
下表に、ディレクトリ選択ダイアログのプロパティのうち、設定を意識する必要がある主なプロパティを示す。<br>
<br>
<br>
<center>表. StorageProviderクラスの主なプロパティ<br>
<center>表. StorageProviderクラスの主なプロパティ<br>
635行目: 591行目:
</center>
</center>
<br>
<br>
==== 使用例 ====
以下の例では、指定された開始位置 ("/usr/local/bin") からディレクトリ選択ダイアログを開き、ユーザが選択したディレクトリのパスを取得している。<br>
以下の例では、指定された開始位置 ("/usr/local/bin") からディレクトリ選択ダイアログを開き、ユーザが選択したディレクトリのパスを取得している。<br>
<br>
<br>
670行目: 628行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
 
==== ディレクトリパスのURLデコード ====
==== Filtersプロパティ (ファイルの種類) の設定 ====
Avalonia UIのストレージシステムは、内部でパスの処理を適切に行うように設計されている。<br>
そのため、IStorageFolder.GetPathAsyncメソッドは、デコードされたパスを返す。<br>
<br>
しかし、もしパスに特殊文字が含まれている場合や何らかの理由でURLエンコードされた形式で返される可能性がある場合は、以下に示すようにURLデコードを行うことができる。<br>
<br>
<syntaxhighlight lang="c#">
// 方法 1
using System.Web;
var path = await selectedFolder.GetPathAsync();
var decodedPath = HttpUtility.UrlDecode(path);
System.Diagnostics.Debug.WriteLine($"選択ディレクトリ: {decodedPath}");
</syntaxhighlight>
<br>
<br>
==== 使用例 ====
<syntaxhighlight lang="c#">
// 方法 2
using System.Net;
using System.Linq;
// ディレクトリが空でないことを確認
if (folders.Any())
{
    var selectedFolder = folders.First();
    var path = await selectedFolder.GetPathAsync();  // パスを取得
    var decodedPath = WebUtility.UrlDecode(path);    // パスをデコード
    System.Diagnostics.Debug.WriteLine($"選択ディレクトリ: {decodedPath}");
}
else
{
    System.Diagnostics.Debug.WriteLine("ディレクトリが未選択");
}
</syntaxhighlight>
<br><br>
<br><br>


{{#seo:
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux
|image=/resources/assets/MochiuLogo_Single_Blue.png
}}


__FORCETOC__
__FORCETOC__
[[カテゴリ:C_Sharp]]
[[カテゴリ:C_Sharp]]

2024年10月31日 (木) 06:04時点における最新版

概要

Avalonia UIは、クロスプラットフォームのUI開発フレームワークであり、C#を使用してデスクトップアプリケーションを構築できる。
このフレームワークでは、ダイアログは重要なUIコンポーネントの一つとして位置付けられている。

ダイアログは、ユーザに情報を表示する、または、入力を求めるための一時的なウインドウである。
主に、警告メッセージの表示、確認の要求、データ入力の促進等に使用される。

Avalonia UIでは、標準的なダイアログとカスタムダイアログの両方を実装することができる。
標準的なダイアログには、メッセージボックス、ファイル選択ダイアログ、ディレクトリ選択ダイアログ等が含まれる。
これらは、Avalonia.Dialogsネームスペースに含まれるクラスを使用して簡単に実装することができる。

カスタムダイアログを作成する場合、通常はWindowクラスを継承して、必要なコンテンツやボタンを追加する。
MVVMパターンに従って実装することにより、ビジネスロジックとUIを分離して、保守性の高いコードを記述することができる。

ダイアログの表示方法には同期的なものと非同期的なものがある。
同期的な方法では、ダイアログが閉じられるまでコードの実行がブロックされる。
一方、非同期的な方法では、ダイアログを表示しながら他の処理を続行できる。

Avalonia UIでは、ダイアログのスタイリングも柔軟に行うことができる。
XAMLを使用してダイアログの外観をカスタマイズして、アプリケーション全体のデザインに合わせることが可能である。

ダイアログの結果の処理において、ユーザの選択や入力に基づいて、適切なアクションを実行するようにコードを設計する必要がある。


ファイル選択タイアログ

OpenFileDialogのプロパティ

下表に、ファイル選択ダイアログのプロパティのうち、設定を意識する必要がある主なプロパティを示す。

表. OpenFileDialogの主なプロパティ
プロパティ名 データ型 意味
AllowMultiple bool 複数ファイルの選択を許可するかどうかを指定する。
許可する場合はtrue、単一のファイルのみの場合はfalseを指定する。(既定値 : false)
Directory string ダイアログが開かれる初期ディレクトリを指定する。
Filters List<FileDialogFilter> ダイアログに表示されるファイルタイプを制限する。
InitialFileName string ダイアログに表示される初期ファイル名を指定する。
Title string ファイル選択ダイアログのウインドウタイトルを指定する。


WinFormsにあるような以下に示すプロパティは存在しない。
そのため、Avalonia UIでの代替方法を以下に示す。

  • AddExtension (拡張子が入力されない場合、自動的に拡張子を付けるかどうか)
    Avalonia UIでは、この機能は自動的に処理される。
    Filtersプロパティで指定された拡張子が使用される。

  • CheckFileExistsプロパティ / CheckPathExistsプロパティ
    Avalonia UIでは、これらの検証はファイル選択後に手動で行う必要がある。

  • FileNameプロパティ / FileNamesプロパティ (選択したファイルパスを取得)
    Avalonia UIでは、OpenFileDialogクラスのShowAsyncメソッドの戻り値を使用する。

  • FilterIndexプロパティ (ファイルの種類のプルダウンの選択肢リストの初期選択インデックスを指定)
    Avalonia UIでは、Filtersプロパティを使用してファイルタイプを制御する。
    特定のフィルタを選択する場合は、Filtersリストの順序を調整する。

  • Multiselectプロパティ (複数のファイルを選択できるかどうかを指定)
    Avalonia UIでは、AllowMultipleプロパティを使用する。
    dialog.AllowMultiple = true; // 複数ファイルの選択を許可

  • ReadOnlyCheckedプロパティ (読み取り専用として開くチェックボックスのON/OFFを設定または取得)
  • ShowReadOnlyプロパティ (読み取り専用として開くチェックボックスを表示するかどうかを設定)
    Avalonia UIでは、これらの機能は直接サポートされていない。
    必要に応じてカスタムダイアログを実装する、あるいは、ファイル選択後に読み取り専用の状態を確認・設定するロジックを実装する必要がある。

  • SafeFileNameプロパティ (選択した拡張子を含むファイル名のみ(パスは含まない)を取得)
  • SafeFileNamesプロパティ (選択した複数の拡張子を含むファイル名のみ(パスは含まない)を取得)
    Avalonia UIでは、これらの概念は直接サポートされていない。
    必要に応じて、選択されたファイルパスから安全なファイル名を抽出するロジックを実装する必要がある。

  • ShowHelpプロパティ (ヘルプボタン[?]を表示するかどうかを指定)
    Avalonia UIのファイルダイアログでは、ヘルプ機能は標準では提供されていない。
    必要に応じて、別途ヘルプ機能を実装する必要がある。


Filtersプロパティ (ファイルの種類) の設定

ダイアログで開くことができるファイルの種類は、Filtersプロパティにフィルタ文字列を設定する。

フィルタ文字列の設定を以下に示す。

  • FileDialogFilterクラスの使用
    各フィルタはFileDialogFilterオブジェクトとして定義される。
  • Nameプロパティ
    ユーザに表示されるフィルタの名前。
  • Extensionsプロパティ
    拡張子のリストであり、ワイルドカード (*) を含めずに指定する。
  • 複数の拡張子
    1つのフィルタに複数の拡張子を含めることができる。
  • 全てのファイル
    全てのファイルを表す場合は、拡張子として "*" を使用する。
  • フィルタの順序
    リストに追加した順序でユーザに表示される。


WinFormsとの主な違いを、以下に示す。

  • Avalonia UIでは、拡張子にワイルドカード (*) を含めずに、単に拡張子名のみを指定する。
  • 複数の拡張子やファイルタイプを1つのフィルタにまとめる場合、Extensionsリストに全ての拡張子を追加する。
  • フィルタ間の区切り (|) は使用せず、代わりに別のFileDialogFilterオブジェクトを作成する。


 using Avalonia.Controls;
 using System.Collections.Generic;
 
 public class FileDialogExample
 {
    public void ShowFileDialog()
    {
       var dialog = new OpenFileDialog();
 
       // Filtersプロパティの設定方法 1
       // List<FileDialogFilter>の使用
       dialog.Filters = new List<FileDialogFilter>
       {
          new FileDialogFilter { Name = "すべてのファイル", Extensions = new List<string> { "*" } },
          new FileDialogFilter { Name = "テキストファイル", Extensions = new List<string> { "txt" } },
          new FileDialogFilter { Name = "テキストファイルとすべてのファイル", Extensions = new List<string> { "txt", "*" } },
          new FileDialogFilter { Name = "XMLファイル", Extensions = new List<string> { "xml" } },
          new FileDialogFilter { Name = "HTMLファイル", Extensions = new List<string> { "html", "htm" } },
          new FileDialogFilter { Name = "XMLファイルとHTMLファイルとすべてのファイル", Extensions = new List<string> { "xml", "html", "htm", "*" } },
          new FileDialogFilter { Name = "イメージファイル", Extensions = new List<string> { "png", "jpg", "gif", "bmp" } }
       };
 
       // Filtersプロパティの設定方法 2
       // FiltersのAddメソッドの使用
       dialog.Filters.Add(new FileDialogFilter { Name = "すべてのファイル", Extensions = { "*" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "テキストファイル", Extensions = { "txt" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "テキストファイルとすべてのファイル", Extensions = new List<string> { "txt", "*" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "XMLファイル", Extensions = { "xml" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "HTMLファイル", Extensions = new List<string> { "html", "htm" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "XMLファイルとHTMLファイルとすべてのファイル", Extensions = new List<string> { "xml", "html", "htm", "*" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "イメージファイル", Extensions = new List<string> { "png", "jpg", "gif", "bmp" } });
 
       // ファイル選択ダイアログを表示
       var result = await dialog.ShowAsync(this);
       if (result != null)
       {
          foreach (var path in result)
          {
             System.Console.WriteLine($"Selected file: {path}");
          }
       }
    }
 }


使用例

ダイアログを表示する場合は、OpenFileDialogクラスのShowAsyncメソッドを実行する。
ShowAsyncメソッドは、非同期で動作してTask<string[]>型を返す。
これにより、UIがブロックされることなくファイル選択操作を行うことができる。

ShowAsyncメソッドの戻り値がnullではないこと、および、配列の長さが0より大きいことを常に確認することが重要である。
これにより、ユーザがファイルを選択せずにダイアログを閉じた場合や操作をキャンセルした場合にも適切に対応することができる。

 using Avalonia.Controls;
 using System.Collections.Generic;
 
 var dialog = new OpenFileDialog();
 dialog.Filters.Add(new FileDialogFilter() { Name = "テキストファイル", Extensions = { "txt" } });
 dialog.AllowMultiple = false;
 dialog.Directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
 dialog.Title = "テキストファイルを選択してください";
 
 var result = await dialog.ShowAsync(this);
 if (result != null && result.Length > 0)
 {
    string selectedFilePath    = result[0];  // 単一ファイルの場合
    string[] selectedFilePaths = result;     // 複数ファイルの場合
 
    // 選択されたファイルを処理
    // ...略
 }



ファイル選択タイアログ (StorageProviderクラス)

StorageProviderのプロパティ

下表に、ファイル選択ダイアログのプロパティのうち、設定を意識する必要がある主なプロパティを示す。

表. StorageProviderクラスの主なプロパティ
プロパティ名 データ型 意味
AllowMultiple bool 複数のアイテムの選択を許可するかどうかを指定する。
複数のアイテムを選択する場合 : true
単一のファイルのみの場合 : false (既定値 : false)
FileTypeFilter

(厳密にはプロパティではない)
IReadOnlyList<FilePickerFileType>型 FilePickerOpenOptions等のオプションクラスのプロパティとして使用する。
選択可能なファイルタイプを制限するためのフィルタのリストを指定する。
SuggestedStartLocation

(厳密にはプロパティではない)
IStorageFolder型 ファイルピッカーやフォルダピッカーが開く初期ディレクトリを指定する。
FilePickerOpenOptionsFolderPickerOpenOptions等のオプションクラスのプロパティとして使用する。

未指定またはnullを指定した場合、ファイルピッカーやフォルダピッカーは、システムやアプリケーションのデフォルトの開始位置を使用する。
多くの場合、ユーザのドキュメントディレクトリ、または、最後にファイルピッカーを使用した場所になる。
Title string ファイル選択ダイアログのウインドウタイトルを指定する。


FileTypeFilter (ファイルの種類) の設定

ダイアログで開くことができるファイルの種類は、FilePickerOpenOptionsクラスのFileTypeFilterプロパティにフィルタ文字列を設定する。

フィルタ文字列の設定を以下に示す。

  • FilePickerOpenOptionsクラス (オプションクラス) の使用
    FilePickerOpenOptionsクラスのインスタンスを作成し、そのFileTypeFilterプロパティにフィルタを設定する。

  • FilePickerFileTypeクラスの使用
    各フィルタはFilePickerFileTypeオブジェクトとして定義されます。コンストラクタの引数にフィルタの名前を指定する。

  • Patterns
    Patternsプロパティに、フィルタに含める拡張子のパターンを指定する。

  • 複数の拡張子
    1つのフィルタに複数の拡張子を含めることができる。
    例えば、"HTMLファイル"フィルタでは、"*.html" と "*.htm" の両方を指定する。

  • 全てのファイル
    全てのファイルを表す場合は、拡張子として "*" を使用する。
    例えば、"すべてのファイル"フィルタがこれに該当する。

  • フィルタの順序
    リストに追加した順序でユーザに表示される。
    以下の例では、"すべてのファイル"が最初に表示されて、以降"テキストファイル"、"XMLファイル"等の順で表示される。


この設定により、ユーザは様々なファイルタイプから選択できる。
特定のファイル形式に絞り込む場合や全てのファイルを表示することもできる。


 var storageProvider = TopLevel.GetTopLevel(this)?.StorageProvider;
 
 var options = new FilePickerOpenOptions
 {
    FileTypeFilter = new[] 
    {
       new FilePickerFileType("すべてのファイル") { Patterns = new[] { "*" } },
       new FilePickerFileType("テキストファイル") { Patterns = new[] { "*.txt" } },
       new FilePickerFileType("XMLファイル")     { Patterns = new[] { "*.xml" } },
       new FilePickerFileType("HTMLファイル")    { Patterns = new[] { "*.html", "*.htm" } },
       new FilePickerFileType("Webファイル")     { Patterns = new[] { "*.html", "*.htm", "*.css", "*.js" } },
       new FilePickerFileType("XMLファイルとHTMLファイル") { Patterns = new[] { "*.xml", "*.html", "*.htm" } },
       new FilePickerFileType("イメージファイル") { Patterns = new[] { "*.png", "*.jpg", "*.gif", "*.bmp", "*.webp" } }
    }
 };
 
 var file = await storageProvider.OpenFilePickerAsync(options);


使用例

以下の例では、FilePickerOpenOptionsクラスを使用してstorageProviderクラスを設定した後、ディレクトリ選択ダイアログを開いている。

SuggestedStartLocationやFileTypeFilterは、StorageProviderクラスの直接のプロパティではないことに注意する。

 using Avalonia.Platform.Storage;
 using System.IO;
 using System.Threading.Tasks;
 
 public class MyClass
 {
    public async Task OpenFileAsync()
    {
       var storageProvider = TopLevel.GetTopLevel(this)?.StorageProvider;
       if (storageProvider != null)
       {
          var options = new FilePickerOpenOptions
          {
             SuggestedStartLocation = await StorageProvider.TryGetFolderFromPathAsync($"/usr/local/bin"),
             FileTypeFilter = new[] 
             {
                new FilePickerFileType("Text Files") { Patterns = new[] { "*.txt" } },
                new FilePickerFileType("All Files") { Patterns = new[] { "*" } }
             },
             AllowMultiple = false
          };
 
          var file = await storageProvider.OpenFilePickerAsync(options);
 
          if (file.Count > 0)
          {  // ファイルが選択された場合の処理
             // ...略
          }
       }
    }
 }



ファイル保存タイアログ (SaveFileDialogクラス)

SaveFileDialogのプロパティ

下表に、ファイル選択ダイアログのプロパティのうち、設定を意識する必要がある主なプロパティを示す。

表. SaveFileDialogの主なプロパティ
プロパティ名 データ型 意味
DefaultExtension string ユーザが拡張子を指定しなかった場合に使用される既定の拡張子を設定または取得する。
Directory string ダイアログが開かれる初期ディレクトリを指定する。
Filters List<FileDialogFilter> ファイル種類のフィルタのリストを指定および取得する。
ユーザが選択できるファイル形式を制限するのに使用する。
InitialDirectory string ダイアログが最初に開かれるディレクトリを指定および取得する。
Directoryプロパティと似ているが、こちらはより優先度が高い。
InitialFileName string ダイアログに表示される初期ファイル名を指定する。
ShowOverwritePrompt bool 既存のファイルを上書きする前に確認ダイアログを表示するかどうかを指定および取得する。
Title string ファイル選択ダイアログのウインドウタイトルを指定する。


以下の例では、各プロパティを指定して、ファイル保存ダイアログの動作をカスタマイズしている。

 var saveFileDialog = new SaveFileDialog
 {
    Title = "プロジェクトを保存",
    InitialFileName = "新規プロジェクト",
    Directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
    DefaultExtension = ".proj",
 
    Filters = new List<FileDialogFilter>
    {
        new FileDialogFilter { Name = "プロジェクトファイル", Extensions = { "proj" } },
        new FileDialogFilter { Name = "すべてのファイル", Extensions = { "*" } }
    },
 
    ShowOverwritePrompt = true
 };


Filtersプロパティ (ファイルの種類) の設定

ダイアログで開くことができるファイルの種類は、Filtersプロパティにフィルタ文字列を設定する。

フィルタ文字列の設定を以下に示す。

  • FileDialogFilterクラスの使用
    各フィルタはFileDialogFilterオブジェクトとして定義される。
  • Nameプロパティ
    ユーザに表示されるフィルタの名前。
  • Extensionsプロパティ
    拡張子のリストであり、ワイルドカード (*) を含めずに指定する。
  • 複数の拡張子
    1つのフィルタに複数の拡張子を含めることができる。
  • 全てのファイル
    全てのファイルを表す場合は、拡張子として "*" を使用する。
  • フィルタの順序
    リストに追加した順序でユーザに表示される。


WinFormsとの主な違いを、以下に示す。

  • Avalonia UIでは、拡張子にワイルドカード (*) を含めずに、単に拡張子名のみを指定する。
  • 複数の拡張子やファイルタイプを1つのフィルタにまとめる場合、Extensionsリストに全ての拡張子を追加する。
  • フィルタ間の区切り (|) は使用せず、代わりに別のFileDialogFilterオブジェクトを作成する。


 using Avalonia.Controls;
 using System.Collections.Generic;
 
 public class FileDialogExample
 {
    public void ShowFileDialog()
    {
       var dialog = new SaveFileDialog();
 
       // Filtersプロパティの設定方法 1
       // List<FileDialogFilter>の使用
       dialog.Filters = new List<FileDialogFilter>
       {
          new FileDialogFilter { Name = "すべてのファイル", Extensions = new List<string> { "*" } },
          new FileDialogFilter { Name = "テキストファイル", Extensions = new List<string> { "txt" } },
          new FileDialogFilter { Name = "テキストファイルとすべてのファイル", Extensions = new List<string> { "txt", "*" } },
          new FileDialogFilter { Name = "XMLファイル", Extensions = new List<string> { "xml" } },
          new FileDialogFilter { Name = "HTMLファイル", Extensions = new List<string> { "html", "htm" } },
          new FileDialogFilter { Name = "XMLファイルとHTMLファイルとすべてのファイル", Extensions = new List<string> { "xml", "html", "htm", "*" } },
          new FileDialogFilter { Name = "イメージファイル", Extensions = new List<string> { "png", "jpg", "gif", "bmp" } }
       };
 
       // Filtersプロパティの設定方法 2
       // FiltersのAddメソッドの使用
       dialog.Filters.Add(new FileDialogFilter { Name = "すべてのファイル", Extensions = { "*" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "テキストファイル", Extensions = { "txt" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "テキストファイルとすべてのファイル", Extensions = new List<string> { "txt", "*" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "XMLファイル", Extensions = { "xml" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "HTMLファイル", Extensions = new List<string> { "html", "htm" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "XMLファイルとHTMLファイルとすべてのファイル", Extensions = new List<string> { "xml", "html", "htm", "*" } });
       dialog.Filters.Add(new FileDialogFilter { Name = "イメージファイル", Extensions = new List<string> { "png", "jpg", "gif", "bmp" } });
 
       // ファイル選択ダイアログを表示
       var result = await dialog.ShowAsync(this);
       if (result != null)
       {
          foreach (var path in result)
          {
             System.Console.WriteLine($"Selected file: {path}");
          }
       }
    }
 }


使用例

以下の例では、Avalonia UIを使用してファイル保存ダイアログを実装している。

 using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Interactivity;
 using Avalonia.Markup.Xaml;
 using System;
 using System.IO;
 using System.Threading.Tasks;
 
 public partial class MainWindow : Window
 {
    public MainWindow()
    {
       InitializeComponent();
    }
 
    private void InitializeComponent()
    {
       AvaloniaXamlLoader.Load(this);
    }
 
    // 保存ボタンを押下
    public async void OnSaveButtonClicked(object sender, RoutedEventArgs e)
    {
       try
       {
          string content = "Hello, directory.";  // 保存する内容
          string savedFilePath = await ShowSaveFileDialogAsync();
 
          if (!string.IsNullOrEmpty(savedFilePath))
          {
             await SaveFileAsync(savedFilePath, content);
             Console.WriteLine("成功", $"ファイルを正常に保存: {savedFilePath}");
          }
       }
       catch (Exception ex)
       {
          Console.WriteLine("エラー", $"ファイルの保存中にエラーが発生: {ex.Message}");
       }
    }
 
    // ファイル保存ダイアログを表示して、選択されたファイルパスを返す
    private async Task<string> ShowSaveFileDialogAsync()
    {
       var saveFileDialog = new SaveFileDialog();
 
       // ダイアログのタイトル
       saveFileDialog.Title = "ファイルを保存";
 
       // .txtファイルのフィルタを追加
       saveFileDialog.Filters.Add(new FileDialogFilter { Name = "テキストファイル", Extensions = { "txt" } });
 
       string result = await saveFileDialog.ShowAsync(this);
       return result;
    }
 
    // 指定されたパスにファイルを非同期で保存
    private async Task SaveFileAsync(string filePath, string content)
    {
       await File.WriteAllTextAsync(filePath, content);
    }
 }



ディレクトリ選択タイアログ

OpenFolderDialogクラスのプロパティ

下表に、ディレクトリ選択ダイアログのプロパティのうち、設定を意識する必要がある主なプロパティを示す。

表. OpenFolderDialogクラスの主なプロパティ
プロパティ名 データ型 意味
AllowMultiple bool 複数のアイテムの選択を許可するかどうかを指定する。
複数のアイテムを選択する場合 : true
単一のファイルのみの場合 : false (既定値 : false)
Directory string ダイアログが最初に開くディレクトリのパスを指定する。
ユーザが頻繁にアクセスするディレクトリやアプリケーションのデフォルトディレクトリを初期表示するために使用する。

例: "ドキュメント"ディレクトリを初期ディレクトリとして指定する場合
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
SuggestedStartLocation IStorageFolder型 ダイアログの推奨される開始位置を指定する。
Directoryプロパティの代替として使用できる。
特定のストレージプロバイダ (例: OneDriveディレクトリ) を初期位置として指定する場合に特に有効である。

※注意
この値が設定されている場合、Directoryプロパティよりも優先される。
Title string ディレクトリ選択ダイアログのウインドウタイトルを指定する。


使用例

以下の例では、Avalonia UIを使用してディレクトリ選択ダイアログを使用している。

ダイアログはユーザのデスクトップディレクトリから開始されるが、何らかの理由でデスクトップディレクトリにアクセスできない場合は、ドキュメントディレクトリにフォールバックする。

この方法は、ユーザが頻繁に使用するディレクトリからダイアログを開始することにより、ユーザエクスペリエンスを向上させることができる。
また、SuggestedStartLocationプロパティを使用することで、将来的により柔軟な開始位置の設定 (例: アプリケーション固有のストレージフォルダ等) が可能になる。

 using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Interactivity;
 using System;
 using System.Threading.Tasks;
 
 public partial class MainWindow : Window
 {
    public MainWindow()
    {
       InitializeComponent();
    }
 
    // ディレクトリ選択ボタンのクリックイベントハンドラ
    private async void OnSelectDirectoryClicked(object sender, RoutedEventArgs e)
    {
       try
       {
          // OpenFolderDialogのインスタンスを生成
          var dialog = new OpenFolderDialog
          {
             // ダイアログのタイトルを設定
             Title = "ディレクトリを選択してください",
 
             // 初期ディレクトリを設定
             Directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
          };
 
          // SuggestedStartLocationを設定
          // デスクトップディレクトリを推奨開始位置として使用
          var desktopFolder = await StorageProvider.TryGetFolderFromPathAsync(
                                       Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
          if (desktopFolder != null)
          {
             dialog.SuggestedStartLocation = desktopFolder;
          }
          else
          {  // デスクトップフォルダが取得できない場合は、従来のDirectoryプロパティを使用
             dialog.Directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
          }
 
          // ダイアログを表示して、ディレクトリを選択するまで待機
          string? result = await dialog.ShowAsync(this);
 
          // 結果の処理
          if (result != null)
          {  // 選択されたディレクトリパスを表示
             Console.WriteLine($"{result}");
          }
          else
          {  // ユーザがキャンセルした場合やディレクトリが選択されなかった場合
             Console.WriteLine("ディレクトリが未選択");
          }
       }
       catch (Exception ex)
       {  // 予期せぬエラーが発生した場合
          Console.WriteLine($"エラーが発生: {ex.Message}");
       }
    }
 }



ディレクトリ選択タイアログ (StorageProviderクラス)

StorageProviderクラスのプロパティ

下表に、ディレクトリ選択ダイアログのプロパティのうち、設定を意識する必要がある主なプロパティを示す。

表. StorageProviderクラスの主なプロパティ
プロパティ名 データ型 意味
AllowMultiple bool 複数のアイテムの選択を許可するかどうかを指定する。
複数のアイテムを選択する場合 : true
単一のファイルのみの場合 : false (既定値 : false)
FileTypeFilter IReadOnlyList<FilePickerFileType>型 FilePickerOpenOptions等のオプションクラスのプロパティとして使用する。
選択可能なファイルタイプを制限するためのフィルタのリストを指定する。
SuggestedStartLocation IStorageFolder型 ファイルピッカーやフォルダピッカーが開く初期ディレクトリを指定する。
FilePickerOpenOptionsFolderPickerOpenOptions等のオプションクラスのプロパティとして使用する。

未指定またはnullを指定した場合、ファイルピッカーやフォルダピッカーは、システムやアプリケーションのデフォルトの開始位置を使用する。
多くの場合、ユーザのドキュメントディレクトリ、または、最後にファイルピッカーを使用した場所になる。
Title string ファイル選択ダイアログのウインドウタイトルを指定する。


使用例

以下の例では、指定された開始位置 ("/usr/local/bin") からディレクトリ選択ダイアログを開き、ユーザが選択したディレクトリのパスを取得している。

 using Avalonia.Platform.Storage;
 using System.IO;
 using System.Threading.Tasks;
 
 public class MyClass
 {
    public async Task OpenDirectoryAsync()
    {
       var storageProvider = TopLevel.GetTopLevel(this)?.StorageProvider;
       if (storageProvider != null)
       {
          var options = new FolderPickerOpenOptions
          {
             SuggestedStartLocation = await storageProvider.TryGetFolderFromPathAsync("/usr/local/bin"),
             AllowMultiple = false
          };
 
          var folders = await storageProvider.OpenFolderPickerAsync(options);
 
          if (folders.Count > 0)
          {
             var selectedFolder = folders[0];
             // 選択されたディレクトリに対する処理
             // 例: ディレクトリのパスを取得
             var path = await selectedFolder.GetPathAsync();
             System.Diagnostics.Debug.WriteLine($"選択ディレクトリ: {path}");
          }
       }
    }
 }


ディレクトリパスのURLデコード

Avalonia UIのストレージシステムは、内部でパスの処理を適切に行うように設計されている。
そのため、IStorageFolder.GetPathAsyncメソッドは、デコードされたパスを返す。

しかし、もしパスに特殊文字が含まれている場合や何らかの理由でURLエンコードされた形式で返される可能性がある場合は、以下に示すようにURLデコードを行うことができる。

 // 方法 1
 
 using System.Web;
 
 var path = await selectedFolder.GetPathAsync();
 var decodedPath = HttpUtility.UrlDecode(path);
 System.Diagnostics.Debug.WriteLine($"選択ディレクトリ: {decodedPath}");


 // 方法 2
 
 using System.Net;
 using System.Linq;
 
 // ディレクトリが空でないことを確認
 if (folders.Any())
 {
    var selectedFolder = folders.First();
    var path = await selectedFolder.GetPathAsync();  // パスを取得
    var decodedPath = WebUtility.UrlDecode(path);    // パスをデコード
    System.Diagnostics.Debug.WriteLine($"選択ディレクトリ: {decodedPath}");
 }
 else
 {
    System.Diagnostics.Debug.WriteLine("ディレクトリが未選択");
 }