c# - 使用 ScrollViewer 从中心原点缩放图像在 UWP 中不起作用
问题描述
我正在使用滚动查看器来缩放设置为 Grid.When 的背景的图像。当我从后面的代码中设置按钮单击的缩放级别值时,使用 scrollViewer.ChangeView(horizontalOffset,verticalOffset,zoomFactor) 图像从左上角缩放角,而不是从中心位置。每次在按钮单击时将比例级别增加为 0.1。
在此处查找示例:示例
XAML:
<UserControl Grid.Row="2">
<ScrollViewer x:Name="scrollViewer" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" VerticalScrollMode="Enabled" HorizontalScrollMode="Enabled" ZoomMode="Enabled" >
<Grid x:Name="ImageGrid" VerticalAlignment="Center" HorizontalAlignment="Center" Width="1260" Height="350" >
<Image x:Name="MyImage" Width="1260" Height="210" Source="Assets\EditedImage.jpg" RenderTransformOrigin="0.5, 0.5" />
</Grid>
</ScrollViewer>
</UserControl>
C#:
float count = 1;
private void Btn_Click(object sender, RoutedEventArgs e)
{
count += 0.1f;
var width = this.scrollViewer.ExtentWidth / 2;
var height = this.scrollViewer.ExtentHeight / 2;
scrollViewer.ChangeView(width, height, count);
}
解决方案
您必须计算相对于可滚动区域的偏移量。
XAML
<StackPanel>
<Button Click="ZoomIn_OnButtonClick" Content="Increase Zoom"/>
<ScrollViewer x:Name="ScrollViewer"
HorizontalScrollBarVisibility="Visible"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center">
<Image Stretch="Uniform" Source="Assets\golden_eaglew.jpg" />
</ScrollViewer>
</StackPanel>
解决方案使用ScrollViewer.ChangeView
由于滚动查看器的范围因应用缩放而发生变化,并且在应用滚动偏移后应用缩放,因此您必须通过使用ScrollViewer.ViewChanged
事件将滚动延迟到中心。这是因为可滚动区域受范围大小的影响(例如ScrollableWidth
= ExtentWidth
- ViewportWidth
)。
public MainPage()
{
this.InitializeComponent();
this.ScrollViewer.ViewChanged += ScrollToCenterOnScrollViewerChanged;
}
private void ScrollToCenterOnScrollViewerChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
if (e.IsIntermediate)
{
return;
}
var scrollViewer = sender as ScrollViewer;
scrollViewer.ChangeView(
scrollViewer.ScrollableWidth / 2,
scrollViewer.ScrollableHeight / 2,
null);
}
private void ZoomIn_OnButtonClick(object sender, RoutedEventArgs e)
=> this.ScrollViewer.ChangeView(null, null, this.ScrollViewer.ZoomFactor + 0.1f);
替代解决方案 1:使用ScrollViewer.ZoomToFactor
请注意,此 API 被标记为已弃用,并且不保证在未来的框架版本中可用。
private void ZoomIn_OnButtonClick(object sender, RoutedEventArgs e)
{
this.ScrollViewer.ZoomToFactor(this.ScrollViewer.ZoomFactor + 0.1f);
this.ScrollViewer.ScrollToHorizontalOffset(this.ScrollViewer.ScrollableWidth / 2);
this.ScrollViewer.ScrollToVerticalOffset(this.ScrollViewer.ScrollableHeight / 2);
}
替代解决方案 2:实现自定义ZoomToFactor
方法
private void ZoomToFactor(double zoomFactor, ScrollViewer scrollViewer)
{
if (!(scrollViewer?.Content is FrameworkElement zoomTarget))
{
return;
}
// Apply the zoom to the scroll content
zoomTarget.Width = zoomTarget.ActualWidth * zoomFactor;
zoomTarget.Height = zoomTarget.ActualHeight * zoomFactor;
// Scroll the zoomed scroll content to center
var scaledScrollableWidth = scrollViewer.ExtentWidth * zoomFactor - scrollViewer.ViewportWidth);
var scaledScrollableHeight = scrollViewer.ExtentHeight * zoomFactor - scrollViewer.ViewportHeight;
double horizontalScrollCenterOffset = scaledScrollableWidth / 2;
double verticalScrollCenterOffset = scaledScrollableHeight / 2;
scrollViewer.ScrollToHorizontalOffset(horizontalScrollCenterOffset);
scrollViewer.ScrollToVerticalOffset(verticalScrollCenterOffset);
}
// Usage example
private void ZoomIn_OnButtonClick(object sender, RoutedEventArgs e)
{
ZoomToFactor(1.1, this.ScrollViewer);
}
推荐阅读
- relational-database - OSS和RDS有什么区别
- javascript - React Native:组件异常 - 对象作为 React 子项无效
- wpf - 更改 UI 上的值时,TrulyObservableCollection 没有通知
- ceph - 更改 CEPH 仪表板网址
- sql - 如何在 PowerQuery 中编写 SQL“Top 1”?
- java - 切换选项卡时在 JPanel 上绘图(Net Beans Java Gui 生成器)
- reactjs - 为什么 React 道具没有在事件处理程序中更新
- r - 如何编辑 list.file 中的数据框
- python - 如何让 Discord.py 检测大小写单词格式?
- .net - 从 oraclebulkcopy 获取进度条的运行时