XAMLで始めるWPF入門:ホイールで画像を拡大する拡張メソッド

コンピュータ

ソースコード

ファイル名:ZoomControlSample01.csproj


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

</Project>

ファイル名:MainWindow.xaml.cs



using NxLib.Helper;

namespace ZoomControlSample01;

public partial class MainWindow : System.Windows.Window
{
    public MainWindow()
    {
        InitializeComponent();

        myImage.OnWheelZoom();
    }
}

ファイル名:Helpers\Wiring.cs


using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace NxLib.Helper;
public static class Wiring
{
    // ホイールで拡大するイベントを追加する拡張メソッド
    public static T OnWheelZoom<T>(this T el, bool consume = true)
    where T : FrameworkElement
    {
        el.PreviewMouseWheel += (_, e) =>
        {
            // Ctrlキーが押されている場合のみ拡大縮小
            if ((Keyboard.Modifiers & ModifierKeys.Control) == 0)
                return;

            // 現在の拡大率を取得
            ScaleTransform? st = el.LayoutTransform as ScaleTransform;
            if (st is null)
                st = new ScaleTransform(1.0, 1.0);

            double scale = st.ScaleX;

            // ホイールの方向で拡大縮小
            if (e.Delta > 0)
                scale *= 1.1;  // 拡大
            else
                scale /= 1.1;  // 縮小
            
            // 範囲制限
            scale = Math.Max(1.0, Math.Min(8.0, scale));

            // 拡大率を設定
            st.ScaleX = scale;
            st.ScaleY = scale;

            el.LayoutTransform = st;

            // スクロールイベントを親に伝えない
            if (consume) e.Handled = true;
        };
        return el;
    }
}

ファイル名:App.xaml


<Application x:Class="ZoomControlSample01.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:ZoomControlSample01"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

ファイル名:MainWindow.xaml


<Window x:Class="ZoomControlSample01.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:local="clr-namespace:ZoomControlSample01"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ScrollViewer
            HorizontalScrollBarVisibility="Auto"
            VerticalScrollBarVisibility="Auto">
            <Image x:Name="myImage"
                Source="C:/Users/karet/Pictures/tone-sample1-small.png"
                RenderOptions.BitmapScalingMode="NearestNeighbor"
                Stretch="None"/>
        </ScrollViewer>
    </Grid>
</Window>

実行イメージ

説明

Imageオブジェクトに対し
myImage.OnWheelZoom();
でOnWheelZoom()拡張メソッドを実行することで、ホイールイベントでコントロールが拡大するコードを適用しています。

使うことはなさそうですが、この拡張メソッドをImage以外でButtonなどで実行しても拡大することが確認出来ています。

コメント