我一直在将我的应用程序转换为 MVVM 模式。我正在尝试找出放大功能。
我的项目中有画布面板和椭圆。
问题是只有当鼠标指针位于形状上时,zoomIn 函数才能工作。
我认为我在 XAML 中创建的画布面板的大小与形状大小相同。所以我需要将此缩放功能应用于画布的父级网格控件。我无法实现这一点。
这些是 XAML 代码。
<Window x:Class="CanvasSampleMvvm.View.MainView"
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="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:CanvasSampleMvvm.View"
xmlns:model="clr-namespace:CanvasSampleMvvm.Model"
xmlns:vm="clr-namespace:CanvasSampleMvvm.ViewModel"
mc:Ignorable="d"
Title="MainView" Height="450" Width="800">
<Window.Resources>
<vm:MainViewVM x:Key="vm"/>
</Window.Resources>
<Grid DataContext="{StaticResource vm}">
<ItemsControl ItemsSource="{Binding Path=Shapes}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseWheel">
<i:InvokeCommandAction Command="{Binding ZoomInCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type model:mShape}">
<Path Data="{Binding Geometry}" Stroke="{Binding Stroke}" Fill="{Binding Fill}" RenderTransform="{Binding Transform}" />
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas DataContext="{StaticResource vm}">
<Canvas.RenderTransform>
<ScaleTransform
ScaleX="{Binding Zoomlevel,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
ScaleY="{Binding Zoomlevel,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
CenterX="{Binding ZoomCenterX, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
CenterY="{Binding ZoomCenterY, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Canvas.RenderTransform>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=XPos}" />
<Setter Property="Canvas.Top" Value="{Binding Path=YPos}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</Window>
这些是 ViewModel 代码:
public class MainViewVM : INotifyPropertyChanged
{
public ObservableCollection<mShape> Shapes { get; } = new ObservableCollection<mShape>();
private readonly MatrixTransform transform = new MatrixTransform();
public ZoomInCommand ZoomInCommand { get; set; }
public MainViewVM()
{
ZoomInCommand = new ZoomInCommand(this);
Shapes.Add(new mShape
{
XPos = 100,
YPos = 100,
Stroke = new SolidColorBrush(Color.FromArgb(0xFF, 0x66, 0x66, 0x66)),
Transform = transform,
Geometry = new EllipseGeometry { RadiusX = 50, RadiusY = 50 },
Fill = (SolidColorBrush)new BrushConverter().ConvertFrom("#D3D3D3")
});
}
public void ZoomIn()
{
double scaleFactor = zoomLevel;
Matrix scaleMatrix = Shapes[0].Transform.Matrix;
scaleMatrix.ScaleAt(scaleFactor, scaleFactor, 0, 0);
for (int i = 0; i < Shapes.Count; i++)
{
double x = Shapes[i].XPos;
double y = Shapes[i].YPos;
double sx = x * zoomLevel;
double sy = y * zoomLevel;
Shapes[i].XPos = sx;
Shapes[i].XPos = sy;
Shapes[i].Transform.Matrix = scaleMatrix;
}
}
private double zoomLevel = 1.1;
public double ZoomLevel
{
get { return zoomLevel; }
set
{
zoomLevel = value;
OnPropertyChanged("ZoomLevel");
}
}
private double zoomCenterX;
public double ZoomCenterX
{
get { return zoomCenterX; }
set
{
zoomCenterX = value;
OnPropertyChanged("ZoomCenterX");
}
}
private double zoomCenterY;
public double ZoomCenterY
{
get { return zoomCenterY; }
set
{
zoomCenterY = value;
OnPropertyChanged("ZoomCenterY");
}
}
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
这些是模型类 (mShape)
public class mShape
{
public double XPos { get; set; }
public double YPos { get; set; }
public MatrixTransform Transform { get; set; }
public Geometry Geometry { get; set; }
public Brush Stroke { get; set; }
public Brush Fill { get; set; }
}
这些是 ZoomInCommand 代码:
public class ZoomInCommand : ICommand
{
event EventHandler ICommand.CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public MainViewVM VM { get; set; }
public ZoomInCommand(MainViewVM vm)
{
VM = vm;
}
bool ICommand.CanExecute(object parameter)
{
return true;
}
void ICommand.Execute(object parameter)
{
VM.ZoomIn();
}
}
通过设置
Canvas
a的属性来绘制 a :Brush
Background
这是接收鼠标输入事件所必需的。