前言:因项目中需要用到对图片对象Image控件的放大缩小及移动,且以鼠标为中心点,查了资料,理解后将实现代码记录如下,方便下次使用。
在WPF中要实现控件的缩放和移动,有现成的工具类可以使用,主要是TransformGroup类,ScaleTransform类和TranslateTransform 类。
TransformGroup类是一个组合,下面有一个Children集合,将ScaleTransform和TranslateTransform 丢到集合中,然后将TransformGroup丢给需要缩放平移的控件对象。控件对象如何接收?每个控件都有一个属性叫RenderTransform,专门用来实现控件自身的缩放平移等变换效果。
border.RenderTransform = TransformGroup;//给Border对象设置一个变换组实例
有一个关键点要理解,如果要移动border对象,那么这个border对象是相对于谁而移动?答案是相对于它的父容器。通常我们用Canvas来做父容器。然后在这个Canvas的各种鼠标操作(按下、移动、滑动滚轮、弹起)事件中去实现缩放平移功能。
下面是部分代码说明:
首先是ViewModel部分
private double mouseX = 0;
public double MouseX
{
get{return mouseX;}
set{mouseX=value;RaisePropertyChanged();}
}
private double mouseY = 0;
public double MouseY
{
get{return mouseY;}
set{mouseY=value;RaisePropertyChanged();}
}
private double delta= 0;
public double Delta
{
get{return delta;}
set{delta=value;RaisePropertyChanged();}
}
然后是WPF前端代码部分
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock Text="{Binding MouseX}" Margin="5"/>
<TextBlock Text="{Binding MouseY}" Margin="5"/>
<TextBlock Text="{Binding Delta}" Margin="5"/>
</StackPanel>
<Canvas Grid.Row="1" x:Name="canvas" Background="Black" ClipToBounds="True"
MouseRightButtonDown="Canvas_MouseRightButtonDown"
MouseRightButtonUp="Canvas_MouseRightButtonUp"
MouseLeftButtonDown="Canvas_MouseLeftButtonDown"
MouseLeftButtonUp="Canvas_MouseLeftButtonUp"
MouseMove="Canvas_MouseMove"
MouseWheel="Canvas_MouseWheel">
<Border x:Name="border" Width="200" Height="100" Background="LightCoral">
<Grid>
<Border Width="100" Height="100" CornerRadius="100" Background="LightBlue"/>
<TextBlock Text="Text"/>
</Grid>
</Border>
</Canvas>
</Grid>
最后是cs后台代码部分文章来源:https://www.toymoban.com/news/detail-608695.html
public partial class MainWindow : Window
{
private MainViewModel vm;
private bool isMouseDown=false;
private Point mousePosition=new Point();
private TranslateTransform translateTransform=new TranslateTransform();
private ScaleTransform scaleTransform=new ScaleTransform();
private TransformGroup transformGroup=new TransformGroup();
public MainWindow()
{
InitializeComponent();
vm=DataContext as MainViewModel;
transformGroup.Children.Add(scaleTransform);//定义缩放
transformGroup.Children.Add(translateTransform);//定义移动
border.RenderTransform=transformGroup;//定义变换组
canvas.Loaded+=(s,e)=>
{
//初始化border控件大小适配canvas父容器
var scale = Math.Min(canvas.ActualWidth/border.Width,canvas.ActualHeight/border.Height);
scaleTransform.ScaleX=scale;
scaleTransform.ScaleY=scale;
};
}
private void Canvas_MouseRightButtonDown(object sender,MouseButtonEventArgs e)
{
isMouseDown=true;
mousePosition=e.GetPosition(canvas);
}
private void Canvas_MouseRightButtonUp(object sender,MouseButtonEventArgs e)
{
isMouseDown=false;
}
private void Canvas_MouseLeftButtonDown(object sender,MouseButtonEventArgs e)
{
isMouseDown=true;
mousePosition=e.GetPosition(canvas);
}
private void Canvas_MouseLeftButtonUp(object sender,MouseButtonEventArgs e)
{
isMouseDown=false;
}
private void Canvas_MouseMove(object sender,MouseEventArgs e)
{
var position=e.GetPosition(canvas);
vm.MouseX=position.X;
vm.MouseY=position.Y;
if(isMouseDown)
{
TranslateTransform translateTransform = transformGroup.Children[1] as TranslateTransform ;
translateTransform.X+=position.X-mousePosition.X;
translateTransform.Y+=position.Y-mousePosition.Y;
mousePosition=position;
}
}
private void Canvas_MouseWheel(object sender,MouseWheelEventArgs e)
{
vm.Delta=e.Delta;
double scale=e.Delta*0.001;
var position=e.GetPosition(canvas);
vm.MouseX=position.X;
vm.MouseY=position.Y;
Point inversePoint=transformGroup.Inverse.Transform(position);
ScaleTransform scaleTransform = transformGroup.Children[0] as ScaleTransform;
TranslateTransform translateTransform = transformGroup.Children[1] as TranslateTransform ;
if(scaleTransform.ScaleX+scale<1)return;
scaleTransform.ScaleX+=scale;
scaleTransform.ScaleY+=scale;
translateTransform.X=-1*((inversePoint.X*scaleTransform.ScaleX)-position.X);
translateTransform.Y=-1*((inversePoint.Y*scaleTransform.ScaleY)-position.Y);
}
}
文章来源地址https://www.toymoban.com/news/detail-608695.html
到了这里,关于WPF中实现以鼠标为中心的缩放和移动图片或控件对象的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!