我正在努力使用Windows Phone 8.1(WinRT)应用中的ScrollViewer
。基本上,我想要实现的是使用FileOpenPicker
检索图像,将图像裁剪为固定比例(方形)格式,同时让用户选择图像的一部分和缩放级别,然后使用我的应用中的图像。 完美将是“人物”应用程序中的功能,您可以在其中添加图像到联系人,但如果我能以某种方式让它在没有ScrollView表现得太不稳定的情况下工作,我会满足于此。 / p>
以下是我尝试的其中一个变体:
<ScrollViewer x:Name="SelectedImageScrollViewer"
ZoomMode="Enabled"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Height="300"
Width="300" >
<Image x:Name="SelectedImage"
Source="{Binding SelectedImage}"
MinHeight="300"
MinWidth="300" />
</ScrollViewer>
并在代码隐藏中(在构造函数中):
if (SelectedImage.ActualHeight > SelectedImage.ActualWidth) {
SelectedImage.Width = SelectedImageScrollViewer.ViewportWidth;
}
else {
SelectedImage.Height = SelectedImageScrollViewer.ViewportHeight;
}
就像我说的那样,这并没有真正起作用,并且有几个问题:
ScrollView
内置了这种“橡皮筋”过度滚动功能。虽然我可以就平台一致性达成一致,但这里没有用,而且提到的“人物”应用程序也没有MaxZoomLevel
以外时,缩放不会停止,但图像会在发布后漂移并快速恢复 - 这不是一个良好的用户体验。ScrollView
未显示图像的中心。如何解决这些问题,以及裁剪和缩放图像的最佳方法是什么?如果它作为SDK的一部分在Silverlight(照片选择器)中可用,那就太好了。
答案 0 :(得分:1)
以下解决方案提供了相当不错的用户体验。关于问题清单:
ScrollViewer
解决。MinZoomFactor
为1可确保图像始终填充框架。ScrollView
的偏移量可以在后面的代码中设置。将IsScrollInertiaEnabled
和IsZoomInertiaEnabled
设置为false
可以消除滚动缩放时的一些不稳定行为。图像宽度和高度在SelectedImage_SizeChanged
中设置,因为初始实际尺寸在构造函数中不可用(在呈现页面之前)。
<ScrollViewer Grid.Row="1"
x:Name="SelectedImageScrollViewer"
ZoomMode="Enabled"
IsScrollInertiaEnabled="False"
IsZoomInertiaEnabled="False"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Height="300"
Width="300"
MinZoomFactor="1.0"
MaxZoomFactor="10.0">
<Image x:Name="SelectedImage"
Source="{Binding SelectedImage}"
HorizontalAlignment="Center"
SizeChanged="SelectedImage_SizeChanged" />
</ScrollViewer>
和
private void SelectedImage_SizeChanged(object sender, SizeChangedEventArgs e) {
// Here the proportions of the image are known and the initial size can be set
// to fill the cropping frame depending on the orientation of the image.
if (!_imageProportionsSet) {
if (SelectedImage.ActualWidth != 0) {
double actualHeight = SelectedImage.ActualHeight;
double actualWidth = SelectedImage.ActualWidth;
double viewPortWidth = SelectedImageScrollViewer.ViewportWidth;
double viewPortHeight = SelectedImageScrollViewer.ViewportHeight;
if (actualHeight > actualWidth) {
SelectedImage.Width = viewPortWidth;
double yOffset = (actualHeight - actualWidth) * viewPortWidth / actualHeight;
SelectedImageScrollViewer.ChangeView(0, yOffset, 1);
}
else {
SelectedImage.Height = viewPortHeight;
double xOffset = (actualWidth - actualHeight) * viewPortHeight / actualWidth;
SelectedImageScrollViewer.ChangeView(xOffset, 0, 1);
}
// Do this only once.
_imageProportionsSet = true;
}
}
}
这是可行的。如果您发现任何问题,请不要犹豫,发表评论或提供更好的答案。