Chapter 31

ステップ8-2: 続き

Apterygiformes-zenn
Apterygiformes-zenn
2021.12.29に更新

画像ウィンドウの作成

ソリューションエクスプローラーでプロジェクトを右クリックし、追加 > ウィンドウ (WPF)を選択します。

名前にImageWindowと入力して追加します。
Windowのプロパティを以下のように設定します。

プロパティ 設定値
Style {StaticResource StandardWindowStyle}
Background DarkGray
Height 300
Width 400

ツールボックスのImageをデザイナのGridにドラッグ&ドロップします。
Imageの名前にImage1を設定します。
ImageWidth, Height, HorizontalAlignment, VerticalAlignment, Marginのリセットボタンを押します。

↓↓↓↓↓

画像ウィンドウのロジック記述

WindowMouseLeftButtonDownイベントの処理を書きます。

// 画像部分をつかんでもウィンドウ移動できるようにする
DragMove();

画像を読み込んでImageコントロールに設定するメソッドを作成します。

/// <summary>
/// 画像読み込み
/// </summary>
/// <param name="path">読み込む画像ファイルパス</param>
/// <returns>true:成功/false:失敗</returns>
public bool LoadImage(string path)
{
    if (string.IsNullOrEmpty(path) ||
        !System.IO.File.Exists(path))
    {
        // パスが「空」または「存在しないパス」なら読み込み失敗
        return false;
    }

    // 画像読み込み
    var bmp = new BitmapImage();
    bmp.BeginInit();
    bmp.CacheOption = BitmapCacheOption.OnLoad;
    bmp.UriSource = new Uri(path);
    bmp.EndInit();
    Image1.Source = bmp;

    // 画像ファイル名をタイトルに設定
    Title = System.IO.Path.GetFileName(path);

    // 読み込み成功
    return true;
}

メインウィンドウのロジック記述

開くボタンのClickイベントの処理を作成します。

未定義の関数なのでいつものようにメソッド定義を生成してください。

OpenImageFile();

対応する拡張子一覧を定義します。

/// <summary>
/// 表示できる画像の拡張子一覧
/// </summary>
private static readonly List<string> ImageExtensions = new()
{
    ".bmp",
    ".gif",
    ".ico",
    ".jpeg",
    ".jpg",
    ".png",
    ".tif",
    ".tiff",
};

OpenImageFileのメソッドの中身を書きます。

// 画像選択ダイアログ用フィルタ文字列(「*.xxx;*.xxx;*.xxx」の形式)
string imgFilter =
    string.Join(";", ImageExtensions.Select(ext => $"*{ext}"));

// ダイアログ生成
var dialog = new OpenFileDialog()
{
    Title = "画像を選択してください。",
    Filter = $"画像ファイル|{imgFilter}| すべてのファイル|*.*",
    Multiselect = true,
};

// ダイアログ表示
if (dialog.ShowDialog() == true)
{
    foreach (var f in dialog.FileNames)
    {
        // 画像表示
        ShowImage(f);
    }
}

エラーの出た箇所をCtrl + .で解消します。
生成したShowImageメソッドの引数名をpathに書き換えます。

📘他の書き方(imgFilter)
書き方A
string imgFilter =
    string.Join(";", ImageExtensions.Select(
        (string x) => "*" + x)
    );
書き方B
List<string> imageExtensions2 = new();

foreach (var ext in ImageExtensions)
{
    imageExtensions2.Add("*" + ext);
}

string imgFilter = string.Join(";", imageExtensions2);

ファイル選択ダイアログはMultiselecttrueにして複数選択できるようにします。

ShowImageメソッドの中身を書きます。

// 拡張子チェック
if (!ImageExtensions.Any(
    ext => path.EndsWith(ext, StringComparison.OrdinalIgnoreCase)))
{
    // 対象外の拡張子は処理しない
    return;
}

// 画像表示画面生成
var window = new ImageWindow();

// 画像表示画面に画像設定
if (window.LoadImage(path))
{
    // 画面表示
    window.Show();
}

ShowImageメソッドの引数pathの末尾が、画像拡張子一覧(ImageExtensions)で一致するものがないか大文字/小文字の区別なしで比較します。
一致するものが1つでもあればAnytrueを返します。

https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.select?view=net-6.0
https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.any?view=net-6.0

閉じるボタンのClickイベントには以下を書きます。

CloseAllSubWindow();

CloseAllSubWindowメソッドには以下を書きます。

foreach (Window w in App.Current.Windows)
{
    if (w == this)
    {
        // 自身(メイン画面)は対象外
        continue;
    }

    // 閉じる
    w.Close();
}

WindowClosingイベントには以下を書きます。

CloseAllSubWindow();

実行

実行してみます。

画像を開くボタンを押して画像ファイルを選択し、開くボタンを押します。

↓↓↓↓↓↓

画像を拡大/縮小してみます。

すべての画像を閉じるボタンを押します。

画像ウィンドウが全部終了しました。