Thumbというコントロールはドラッグで移動することが出来ます。
そのコントロールに画像を被せて、さらにScaleTransformで拡大・縮小することで、画像を拡大・縮小・移動するプログラムにしてみました。
そのコントロールに画像を被せて、さらにScaleTransformで拡大・縮小することで、画像を拡大・縮小・移動するプログラムにしてみました。
プロジェクトの作成
PowerShellで実行。要dotnet.exe
mkdir MoveZoomImage
cd MoveZoomImage
dotnet new wpf
dotnet add package Microsoft.Xaml.Behaviors.WPF
dotnet add package ReactiveProperty.WPF
code .
ソースコード
ファイル名:MainWindow.xaml
<Window x:Class="MoveZoomImage.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:i="clr-namespace:Microsoft.Xaml.Behaviors;assembly=Microsoft.Xaml.Behaviors"
xmlns:interactivity="clr-namespace:Reactive.Bindings.Interactivity;assembly=ReactiveProperty.WPF"
xmlns:local="clr-namespace:MoveZoomImage"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<Canvas
Background="Gray"
Height="450"
Width="800">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseWheel">
<interactivity:EventToReactiveCommand Command="{Binding MouseWheelCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Thumb
Canvas.Left="{Binding ThumbLeft.Value}"
Canvas.Top="{Binding ThumbTop.Value}">
<Thumb.RenderTransform>
<ScaleTransform ScaleX="{Binding ZoomScale.Value}" ScaleY="{Binding ZoomScale.Value}"/>
</Thumb.RenderTransform>
<i:Interaction.Triggers>
<i:EventTrigger EventName="DragCompleted">
<interactivity:EventToReactiveCommand Command="{Binding DragCompletedCommand}" />
</i:EventTrigger>
<i:EventTrigger EventName="DragStarted">
<interactivity:EventToReactiveCommand Command="{Binding DragStartedCommand}" />
</i:EventTrigger>
<i:EventTrigger EventName="DragDelta">
<interactivity:EventToReactiveCommand Command="{Binding DragDeltaCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Thumb.Template>
<ControlTemplate TargetType="Thumb">
<Image
Stretch="None"
Source="E:\csharp\wpf\MoveZoomImage\logo.png">
</Image>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Canvas>
</Grid>
</Window>
ファイル名:MainWindowViewModel.cs
using Reactive.Bindings;
using System.Reactive.Disposables;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using System.Windows;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.IO;
using System.Windows.Input;
namespace MoveZoomImage
{
public class MainWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name) =>
PropertyChanged(this, new PropertyChangedEventArgs(name));
public ReactiveProperty<double> ThumbLeft { get; private set; } = new(0.0d);
public ReactiveProperty<double> ThumbTop { get; private set; } = new(0.0d);
public ReactiveProperty<double> ZoomScale { get; private set; } = new(1.0d);
public ReactiveCommand<System.Windows.Controls.Primitives.DragCompletedEventArgs> DragCompletedCommand { get; } = new();
public ReactiveCommand<System.Windows.Controls.Primitives.DragStartedEventArgs> DragStartedCommand { get; } = new();
public ReactiveCommand<System.Windows.Controls.Primitives.DragDeltaEventArgs> DragDeltaCommand { get; } = new();
public ReactiveCommand<MouseWheelEventArgs> MouseWheelCommand { get; } = new();
public MainWindowViewModel()
{
PropertyChanged += (o, e) => {};
DragCompletedCommand.Subscribe(e =>
{
// ドラッグ完了
ThumbLeft.Value = ThumbLeft.Value + e.HorizontalChange;
ThumbTop.Value = ThumbTop.Value + e.VerticalChange;
});
DragStartedCommand.Subscribe(e=>
{
// ドラッグ開始
});
DragDeltaCommand.Subscribe(e =>
{
// ドラッグ中
//ThumbLeft.Value = ThumbLeft.Value + e.HorizontalChange;
//ThumbTop.Value = ThumbTop.Value + e.VerticalChange;
});
MouseWheelCommand.Subscribe(e =>
{
// ホイール
double x = ZoomScale.Value;
if (e.Delta < 0)
x = x - 0.25d;
else
x = x + 0.25d;
if (x < 0.25d)
x = 0.25d;
if (x > 8.0d)
x = 8.0d;
ZoomScale.Value = x;
});
}
}
}
実行
dotnet run
起動すると画像が表示されます。
画像をマウスでドラックすると画像が移動します。
マウスホイールを回すと画像が拡大縮小します。
GIF
追記:20240514
DragDeltaCommand内でThumbを移動していましたがDragCompletedCommandで移動するように変更しました。
等倍での移動は問題なさそうですが、拡大縮小した状態で移動距離がとても大きな数字になっており、Windowの外に移動するので画像が消えてしまいます。対策が思いつかないので、とりあえずDragCompletedCommandで一気に移動するようにしてみました。
移動の軌跡が見えなので見た目は悪いのですが、消えてしまうよりまだ良いかと思います。
コメント