📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

 
21行目: 21行目:
<br>
<br>
ダイアログの結果の処理において、ユーザの選択や入力に基づいて、適切なアクションを実行するようにコードを設計する必要がある。<br>
ダイアログの結果の処理において、ユーザの選択や入力に基づいて、適切なアクションを実行するようにコードを設計する必要がある。<br>
<br><br>
== カスタムメッセージボックス ==
==== プロパティ ====
カスタムメッセージボックスでは、多くのプロパティや設定を追加して、より柔軟で機能的なメッセージボックスを定義することができる。<br>
<br>
===== ウインドウのプロパティ =====
* Width / Height
*: ウインドウの固定サイズを設定
* MinWidth / MinHeight
*: 最小サイズを設定
* MaxWidth / MaxHeight
*: 最大サイズを設定
* WindowStartupLocation
*: ウインドウの初期位置を指定
*: 例: 中央、オーナーの中央
* Topmost
*: 常に最前面に表示するかどうかを指定する。
* ShowInTaskbar
*: タスクバーに表示するかどうかを指定する。
* CanResize
*: ユーザによるリサイズを許可するかどうかを指定する。
* SystemDecorations
*: ウインドウの装飾 (最小化、最大化、閉じるボタン) の表示設定
<br>
===== コンテンツのレイアウト =====
* Padding
*: ウイィンドウ内のコンテンツの余白
* Margin
*: 各コントロールの外側の余白
* HorizontalAlignment / VerticalAlignment
*: コンテンツの水平・垂直方向の配置
* Spacing
*: StackPanel内の要素間の間隔
<br>
===== テキストブロックのプロパティ =====
* FontSize
*: フォントサイズ
* FontWeight
*: フォントの太さ
* FontFamily
*: フォントファミリー
* Foreground
*: テキストの色
* TextWrapping
*: テキストの折り返し設定
* TextAlignment
*: テキストの配置
<br>
===== ボタンのプロパティ =====
* Width / Height
*: ボタンのサイズ
* Background
*: ボタンの背景色
* Foreground
*: ボタンのテキスト色
* BorderBrush / BorderThickness
*: ボタンの枠線の色と太さ
* CornerRadius
*: ボタンの角の丸み
<br>
===== アイコンとイメージ =====
メッセージボックスにアイコンやイメージを追加する。<br>
例: 警告、エラー、情報等<br>
<br>
===== 複数のボタン =====
* [OK]、[キャンセル]、[Yes]、[NO]等の複数のボタンを追加する。
* 各ボタンに対応するDialogResultを設定する。
<br>
===== カスタムスタイル =====
* Styleプロパティを使用して、ウインドウや各コントロールにカスタムスタイルを適用する。
<br>
===== アニメーション =====
* 表示時や閉じる時のアニメーション効果を追加する。
<br>
===== キーボードショートカット =====
[Esc]キーでウインドウを閉じる等、キーボードショートカットを設定する。<br>
<br>
===== アクセシビリティ =====
AutomationProperties.NameやAutomationProperties.HelpTextを使用して、スクリーンリーダーのサポートを改善する。<br>
<br>
==== 使用例 1 ====
以下の例では、Avalonia UIを使用してカスタムメッセージボックスを定義している。<br>
<br>
"OK"という名前のボタンを検索しているため、ボタンにNameプロパティに"OK"を設定する、あるいは、別の方法でボタンを参照する必要があることに注意する。<br>
<br>
<syntaxhighlight lang="c#">
// メッセージボックスを表示するヘルパーメソッド
// タイトルとメッセージを受け取り、カスタムメッセージボックスを非同期に表示する
private async Task ShowMessageAsync(string title, string message)
{
    await new MessageBoxWindow(title, message).ShowDialog(this);
}
// シンプルなメッセージボックスウィンドウのクラス
public class MessageBoxWindow : Window
{
    public MessageBoxWindow(string title, string message)
    {
      Title = title;
      // ウインドウのサイズは内容に合わせて自動調整される
      SizeToContent = SizeToContent.WidthAndHeight;
      // StackPanelを使用して、本文と[OK]ボタンを縦に配置
      Content = new StackPanel
      {
          Children =
          {
            new TextBlock { Text = message, Margin = new Thickness(20) },
            new Button { Content = "OK", HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center, Margin = new Thickness(0, 0, 0, 20) }
          }
      };
      // [OK]ボタンがクリックされた時にウインドウを閉じるイベントハンドラを設定
      this.FindControl<Button>("OK").Click += (sender, args) => Close();
    }
}
</syntaxhighlight>
<br>
==== 使用例 2 ====
以下の例では、Avalonia UIを使用して、カスタムメッセージボックスにアイコン、イメージ、複数のボタンを追加・定義している。<br>
<br>
* アイコンおよびイメージの追加
*: MessageBoxIcon enumを使用して、情報、警告、エラー、質問のアイコンを選択することができる。
*: アイコンはGrid内の左側に配置される。
*: アイコン画像は、"avares://"URIを使用して参照される。
*: 実際の使用時には、プロジェクト内の正しいパスに画像ファイルを配置する必要がある。
*: <br>
* 複数のボタンの追加
*: MessageBoxButton enumを使用して、OK、OKCancel、YesNo、YesNoCancelのボタン構成を選択することができる。
*: ボタンはStackPanel内に動的に追加されて、右下に配置される。
*: 各ボタンにはクリックイベントハンドラが設定され、適切な結果 (true、false、null) を返す。
<br>
<syntaxhighlight lang="c#">
using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.Media.Imaging;
using System;
using System.Threading.Tasks;
public class CustomMessageBox : Window
{
    public enum MessageBoxButton
    {
      OK,
      OKCancel,
      YesNo,
      YesNoCancel
    }
    public enum MessageBoxIcon
    {
      None,
      Information,
      Warning,
      Error,
      Question
    }
    private TaskCompletionSource<bool?> _resultTcs;
    public CustomMessageBox()
    {
      this.InitializeComponent();
    }
    private void InitializeComponent()
    {
      Title = "Message";
      SizeToContent = SizeToContent.WidthAndHeight;
      MinWidth  = 300;
      MinHeight = 100;
    }
    public static Task<bool?> Show(Window owner, string message, string title = "Message",
                                  MessageBoxButton buttons = MessageBoxButton.OK, MessageBoxIcon icon = MessageBoxIcon.None)
    {
      var messageBox = new CustomMessageBox
      {
          Title = title
      };
      var grid = new Grid
      {
          ColumnDefinitions = new ColumnDefinitions("Auto,*"),
          RowDefinitions = new RowDefinitions("*,Auto")
      };
      // アイコンの指定
      if (icon != MessageBoxIcon.None)
      {
          var iconImage = new Image
          {
            Width  = 32,
            Height = 32,
            Margin = new Thickness(10),
            VerticalAlignment = VerticalAlignment.Top
          };
          string iconPath = icon switch
          {
            MessageBoxIcon.Information => "avares://YourAssemblyName/Assets/information.png",
            MessageBoxIcon.Warning => "avares://YourAssemblyName/Assets/warning.png",
            MessageBoxIcon.Error => "avares://YourAssemblyName/Assets/error.png",
            MessageBoxIcon.Question => "avares://YourAssemblyName/Assets/question.png",
                _ => throw new ArgumentOutOfRangeException(nameof(icon))
          };
          iconImage.Source = new Bitmap(iconPath);
          Grid.SetColumn(iconImage, 0);
          Grid.SetRow(iconImage, 0);
          grid.Children.Add(iconImage);
      }
      // メッセージを指定
      var messageTextBlock = new TextBlock
      {
          Text        = message,
          TextWrapping = Avalonia.Media.TextWrapping.Wrap,
          Margin = new Thickness(10)
      };
      Grid.SetColumn(messageTextBlock, 1);
      Grid.SetRow(messageTextBlock, 0);
      grid.Children.Add(messageTextBlock);
      // ボタンの指定
      var buttonPanel = new StackPanel
      {
          Orientation        = Orientation.Horizontal,
          HorizontalAlignment = HorizontalAlignment.Right,
          Margin = new Thickness(0, 10, 10, 10)
      };
      void AddButton(string content, bool? dialogResult)
      {
          var button = new Button { Content = content, MinWidth = 60, Margin = new Thickness(5, 0, 0, 0) };
          button.Click += (_, __) =>
          {
            messageBox._resultTcs.SetResult(dialogResult);
            messageBox.Close();
          };
          buttonPanel.Children.Add(button);
      }
      switch (buttons)
      {
          case MessageBoxButton.OK:
              AddButton("OK", true);
              break;
          case MessageBoxButton.OKCancel:
              AddButton("OK", true);
              AddButton("Cancel", false);
              break;
          case MessageBoxButton.YesNo:
              AddButton("Yes", true);
              AddButton("No", false);
              break;
          case MessageBoxButton.YesNoCancel:
              AddButton("Yes", true);
              AddButton("No", false);
              AddButton("Cancel", null);
              break;
      }
      Grid.SetColumn(buttonPanel, 1);
      Grid.SetRow(buttonPanel, 1);
      grid.Children.Add(buttonPanel);
      messageBox.Content = grid;
      messageBox._resultTcs = new TaskCompletionSource<bool?>();
      if (owner != null)
      {
          messageBox.ShowDialog(owner);
      }
      else
      {
          messageBox.Show();
      }
      return messageBox._resultTcs.Task;
    }
}
</syntaxhighlight>
<br><br>
<br><br>