每个人,
我有一个WPF应用程序,它有一个画布,我已经包装在滚动查看器中。我在状态栏中有一个滑块,允许用户放大和缩小(就像Win 7的mspaint一样)。
以下是一些XAML:
<ScrollViewer Name="Map"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<Canvas x:Name="WallsCanvas" Height="800" Width="1000" ClipToBounds="True">
<Canvas.LayoutTransform>
<ScaleTransform x:Name="WallsCanvasScale"
ScaleX="1" ScaleY="1" />
</Canvas.LayoutTransform>
</Canvas>
</ScrollViewer>
当我放大并且滚动条可见时,滚动条,无论它们在何处设置,都会跳到中间。
滚动条的值保持不变,但最大值增加。
我可以做些什么来让他们......如果他们在右下角,放大或缩小后留在右下角?
BTW,这是我的放大和缩小代码:
private void SliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
var scales = new []{.125, .25, .5, 1, 2, 4, 8};
var scale = scales[(int)((Slider) sender).Value];
ScaleChanged(scale, WallsCanvasScale);
}
private static void ScaleChanged(double scale, ScaleTransform st)
{
st.ScaleX = scale;
st.ScaleY = scale;
}
所以,我的代码中没有火箭科学但是......
更新构思:如果我可以访问滚动条的值和最大值,我可以获得两者之间的百分比,然后在缩放(缩放)之后我可以重新应用滚动条的值作为百分比最大值?????但是值和最大值在哪里?
任何帮助将不胜感激。我不能认为我是唯一一个有这个问题的人,因为MSPaint(Windows 7版本)正常工作,我认为它是一个XAML应用程序。
这是最小工作示例项目(VS 2010)的link(http://www.leesaunders.net/examples/zoomexample/zoomexample.zip)。当你运行它时,只需移动滚动条然后放大一个级别,你就会立即看到问题。
答案 0 :(得分:3)
您只需要抵消因缩放而产生的偏移,因为它从(0,0)缩放。这有点复杂,但这里是样本中方法的样子草图:
private void SliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
var slider = (Slider)sender;
if (!slider.IsLoaded)
{
slider.Loaded += (s, le) => SliderValueChanged(sender, e);
return;
}
var scales = new[] { .125, .25, .5, 1, 2, 4, 8 };
var scale = scales[(int)((Slider)sender).Value];
// The "+20" are there to account for the scrollbars... i think. Not perfectly accurate.
var relativeMiddle = new Point((Map.ActualWidth + 20) / 2, (Map.ActualHeight + 20) / 2);
var oldLocation = CanvasScale.Transform(TemplateCanvas.PointFromScreen(relativeMiddle));
ScaleChanged(scale, CanvasScale);
var newLocation = CanvasScale.Transform(TemplateCanvas.PointFromScreen(relativeMiddle));
var shift = newLocation - oldLocation;
Map.ScrollToVerticalOffset(Map.VerticalOffset + shift.Y);
Map.ScrollToHorizontalOffset(Map.HorizontalOffset + shift.X);
lblScale.Content = scale.ToString("P1").Replace(".0", string.Empty);
}
应该是不言自明的;在缩放之前和之后测量中心的位置,以计算该点的移位,然后将其添加到当前滚动位置。