Grid
Canvas
Height
Width
作为
CanvasHeight * ScaleY
和
CanvasWidth * ScaleX
以这种方式分别为控件和
ScrollViewer
会注意到的。
我已经创建了一个演示应用程序,它将帮助您理解这个问题,顺便说一句,我在这里发布的代码按照您期望的方式工作:
值转换器.cs
public class ValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double originalValue = System.Convert.ToDouble(value);
double multiplier = System.Convert.ToDouble(parameter);
return originalValue * multiplier;
}
public object ConvertBack(object value, Type targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
视图模型
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private double gridHeight = 500.0;
public double GridHeight
{
get { return gridHeight; }
private set { gridHeight = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(GridHeight))); }
}
private double gridWidth = 500.0;
public double GridWidth
{
get { return gridWidth; }
private set { gridWidth = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(GridWidth))); }
}
private int scaleX = 1;
public int ScaleX
{
get { return scaleX; }
set
{
if (value > 0)
{
var oldScaleX = scaleX;
scaleX = value;
GridWidth *= (double)scaleX / oldScaleX;
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ScaleX)));
}
}
private int scaleY = 1;
public int ScaleY
{
get { return scaleY; }
set
{
if (value > 0)
{
var oldScaleY = scaleY;
scaleY = value;
GridHeight *= (double)scaleY / oldScaleY;
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ScaleY)));
}
}
}
主窗口.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
private void btnScaleXIncrease_Click(Object sender, RoutedEventArgs e)
{
((ViewModel)DataContext).ScaleX++;
}
private void btnScaleXDecrease_Click(Object sender, RoutedEventArgs e)
{
((ViewModel)DataContext).ScaleX--;
}
private void btnScaleYIncrease_Click(Object sender, RoutedEventArgs e)
{
((ViewModel)DataContext).ScaleY++;
}
private void btnScaleYDecrease_Click(Object sender, RoutedEventArgs e)
{
((ViewModel)DataContext).ScaleY--;
}
}
主窗口
<Window x:Class="WpfApplicationTest.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:WpfApplicationTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<local:ValueConverter x:Key="ValueConverter" />
</ResourceDictionary>
</Window.Resources>
<DockPanel>
<DockPanel DockPanel.Dock="Top">
<GroupBox Header="Scale X" DockPanel.Dock="Left" Width="100">
<StackPanel Orientation="Horizontal">
<Button Width="40" Click="btnScaleXIncrease_Click">+</Button>
<Button Width="40" Click="btnScaleXDecrease_Click">-</Button>
</StackPanel>
</GroupBox>
<GroupBox Header="Scale Y" DockPanel.Dock="Right" Width="100">
<StackPanel Orientation="Horizontal">
<Button Width="40" Click="btnScaleYIncrease_Click">+</Button>
<Button Width="40" Click="btnScaleYDecrease_Click">-</Button>
</StackPanel>
</GroupBox>
<StackPanel></StackPanel>
</DockPanel>
<ScrollViewer HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible">
<Grid Width="{Binding GridWidth, Mode=OneWay}" Height="{Binding GridHeight, Mode=OneWay}">
<Canvas Height="{Binding GridHeight, Mode=OneTime}" Width="{Binding GridWidth, Mode=OneTime}"
Background="Gray">
<Ellipse Fill="Yellow" Height="500" Width="500" StrokeThickness="2" Stroke="Black"/>
<Canvas.RenderTransform>
<ScaleTransform ScaleX="{Binding ScaleX}" ScaleY="{Binding ScaleY}"
CenterX="{Binding GridWidth, Converter={StaticResource ValueConverter}, ConverterParameter=0.5, Mode=OneTime}"
CenterY="{Binding GridHeight, Converter={StaticResource ValueConverter}, ConverterParameter=0.5, Mode=OneTime}" />
</Canvas.RenderTransform>
</Canvas>
</Grid>
</ScrollViewer>
</DockPanel>
</Window>