定义图片放大的Xaml文件:
View Code
<UserControl x:Class="Win8_ScorllViewer.LodingImage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Win8_ScorllViewer" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="Transparent" PointerPressed="LayoutRoot_PointerPressed_1" > <Grid.RowDefinitions> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="160"></RowDefinition> </Grid.RowDefinitions> <Rectangle x:Name="rectShadow" Grid.RowSpan="2"></Rectangle> <Canvas Grid.RowSpan="2"> <!-- 注意 Stretch="Fill" --> <Image x:Name="img" PointerMoved="img_PointerMoved_1" PointerReleased="img_PointerReleased_1" PointerPressed="img_PointerPressed_1" PointerEntered="img_PointerEntered_1" PointerExited="img_PointerExited_1" Stretch="Fill" > <Image.RenderTransform> <ScaleTransform x:Name="st" /> </Image.RenderTransform> </Image> </Canvas> <StackPanel HorizontalAlignment="Center" Orientation="Vertical" VerticalAlignment="Center" Grid.Row="1"> <StackPanel Margin="30" Orientation="Horizontal"> <Rectangle x:Name="rectProcess" Width="180" Height="10" RadiusX="3" RadiusY="3" > <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5"> <GradientStop Color="#4682b4" Offset="0" /> <GradientStop Color="#4682b4" x:Name="blue1" Offset="0" /> <GradientStop Color="gray" x:Name="gray1" Offset="0" /> <GradientStop Color="gray" Offset="1" /> </LinearGradientBrush> </Rectangle.Fill> <Rectangle.Resources> <Storyboard x:Name="sbRect"> </Storyboard> </Rectangle.Resources> </Rectangle> <TextBlock Margin="10 0 0 0" Text="正在加载 85%" x:Name="TxtLoading" HorizontalAlignment="Center" Foreground="Black" VerticalAlignment="Center" /> </StackPanel> <Rectangle Width="30" Height="30" Fill="Red" RadiusX="3" RadiusY="3" ></Rectangle> </StackPanel> </Grid> </UserControl>
后台文件:
View Code
public sealed partial class LodingImage : UserControl { /// <summary> /// 屏幕大小 /// </summary> Rect bounds = Window.Current.Bounds; private string _uri = string.Empty; private Uri _baseUri = new Uri("ms-appx:///"); BitmapImage bitmapImage; /// <summary> /// 是否可以移动 /// </summary> private bool canMove = false; /// <summary> /// 鼠标/手指 移动前的坐标 /// </summary> PointerPoint startPoint; /// <summary> /// 加载时图片默认Canvas.Left Canvas.Top坐标 /// </summary> Point defaultPosition; /// <summary> /// 屏幕的中心位置 /// </summary> Point defaultPoint; /// <summary> /// 当前移动位置和默认坐标的相差位移 /// </summary> Point destancePoint = new Point(0, 0); /// <summary> /// 要显示的URI地址 /// </summary> public string Uri { set { bitmapImage = new BitmapImage(); img.Source = bitmapImage; bitmapImage.UriSource = new Uri(_baseUri, value);//测试用本地图片 SetImageProperty(); TxtLoading.Visibility = rectProcess.Visibility = Visibility.Visible; bitmapImage.DownloadProgress += bitmapImage_DownloadProgress; bitmapImage.ImageFailed += bitmapImage_ImageFailed; bitmapImage.ImageOpened += bitmapImage_ImageOpened; } get { return _uri; } } private double _scaleRate = 0.2; public double ScaleRate { get { return _scaleRate; } set { _scaleRate = value; } } public Image OriginalImage { set { img.Height = value.Height; img.Width = value.Width; img.Source = value.Source; } get { return img; } } public Stretch ImageStretch { get { return img.Stretch; } set { img.Stretch = value; } } public LodingImage() { this.InitializeComponent(); this.Loaded += LodingImage_Loaded; this.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } public void Show() { this.Visibility = Windows.UI.Xaml.Visibility.Visible; } void LodingImage_Loaded(object sender, RoutedEventArgs e) { rectShadow.Width = bounds.Width; rectShadow.Height = bounds.Height; rectShadow.Fill = new SolidColorBrush(Colors.Gray); rectShadow.Opacity = 0.3; } void bitmapImage_DownloadProgress(object sender, DownloadProgressEventArgs e) { double moveRate = e.Progress * 1.0 / 100; gray1.Offset += moveRate; blue1.Offset += moveRate; TxtLoading.Text = string.Format("正在加载 {0}%", e.Progress); } void bitmapImage_ImageFailed(object sender, ExceptionRoutedEventArgs e) { TxtLoading.Text = string.Format("加载失败"); } void bitmapImage_ImageOpened(object sender, RoutedEventArgs e) { TxtLoading.Visibility = rectProcess.Visibility = Visibility.Collapsed; } void ReLoad() { bitmapImage = new BitmapImage(); } private void img_PointerEntered_1(object sender, PointerRoutedEventArgs e) { img.PointerWheelChanged += img_PointerWheelChanged; } void img_PointerWheelChanged(object sender, PointerRoutedEventArgs e) { var pointerPointer = e.GetCurrentPoint(img); //注意pointerPoint.Properties属性 提供我们想要的很多属性 var delta = pointerPointer.Properties.MouseWheelDelta; double rate = ScaleRate; if (delta < 0) { rate = rate * -1; } if (st.ScaleX + rate <= 0.4) { return; } /* * 如果产生了相对位移的话即图片位置被移动过 * 则处理缩放的大小和相对位移做运算 * bug 当缩小时应该为下面的算法 * */ if (rate < 0) { if (destancePoint.Y > 0) { double dY = Math.Abs((rate * img.Height) / 2); double moveTop = Convert.ToDouble(img.GetValue(Canvas.TopProperty)); if (dY >= Math.Abs(destancePoint.Y)) { img.SetValue(Canvas.TopProperty, defaultPosition.Y); destancePoint.Y = 0; } else { destancePoint.Y -= dY; img.SetValue(Canvas.TopProperty, moveTop - dY); } } else if (destancePoint.Y < 0) { double dY = Math.Abs((rate * img.Height) / 2); double moveTop = Convert.ToDouble(img.GetValue(Canvas.TopProperty)); if (dY >= Math.Abs(destancePoint.Y)) { img.SetValue(Canvas.TopProperty, defaultPosition.Y); destancePoint.Y = 0; } else { destancePoint.Y += dY; img.SetValue(Canvas.TopProperty, moveTop + dY); } } if (destancePoint.X > 0) { double dX = Math.Abs((rate * img.Width) / 2); double moveLeft = Convert.ToDouble(img.GetValue(Canvas.LeftProperty)); if (dX >= Math.Abs(destancePoint.X)) { img.SetValue(Canvas.LeftProperty, defaultPosition.X); destancePoint.X = 0; } else { destancePoint.X -= dX; img.SetValue(Canvas.LeftProperty, moveLeft - dX); } } else if (destancePoint.X < 0) { double dX = Math.Abs((rate * img.Width) / 2); double moveLeft = Convert.ToDouble(img.GetValue(Canvas.LeftProperty)); if (dX >= Math.Abs(destancePoint.X)) { img.SetValue(Canvas.LeftProperty, defaultPosition.X); destancePoint.X = 0; } else { destancePoint.X += dX; img.SetValue(Canvas.LeftProperty, moveLeft + dX); } } } else { } st.ScaleY += rate; st.ScaleX += rate; } private void img_PointerExited_1(object sender, PointerRoutedEventArgs e) { img.PointerWheelChanged -= img_PointerWheelChanged; } private void LayoutRoot_PointerPressed_1(object sender, PointerRoutedEventArgs e) { this.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } private void img_PointerPressed_1(object sender, PointerRoutedEventArgs e) { FrameworkElement element = sender as FrameworkElement; canMove = true; if (element != null) { element.CapturePointer(e.Pointer); } startPoint = e.GetCurrentPoint(LayoutRoot); e.Handled = true; } private void img_PointerMoved_1(object sender, PointerRoutedEventArgs e) { if (canMove) { PointerPoint point = e.GetCurrentPoint(LayoutRoot); if (IsWidthOutBounds()) { double left = double.Parse(img.GetValue(Canvas.LeftProperty).ToString()); double moveToX = (point.Position.X - startPoint.Position.X) + left; destancePoint.X = moveToX - defaultPoint.X + img.Width / 2; double destanceX = Math.Abs(destancePoint.X); if (destanceX <= (img.Width * st.ScaleX - bounds.Width) / 2) { img.SetValue(Canvas.LeftProperty, moveToX); } } if (IsHeightOutBounds()) { double top = double.Parse(img.GetValue(Canvas.TopProperty).ToString()); double moveToY = (point.Position.Y - startPoint.Position.Y) + top; destancePoint.Y = moveToY - defaultPoint.Y + img.Height /2; double destanceY = Math.Abs(destancePoint.Y); if (destanceY <= (img.Height * st.ScaleY - bounds.Height) / 2) { img.SetValue(Canvas.TopProperty, moveToY); } } startPoint = e.GetCurrentPoint(LayoutRoot); } } private void img_PointerReleased_1(object sender, PointerRoutedEventArgs e) { FrameworkElement element = sender as FrameworkElement; element.ReleasePointerCapture(e.Pointer); canMove = false; } private void SetImageProperty() { st.ScaleX = 1.5; st.ScaleY = 1.5; st.CenterX = img.Width / 2; st.CenterY = img.Height / 2; double top = (bounds.Height - img.Height) / 2; double left = (bounds.Width - img.Width) / 2; defaultPosition = new Point(left, top); destancePoint = new Point(0, 0); defaultPoint = new Point(bounds.Width / 2, bounds.Height / 2); img.SetValue(Canvas.TopProperty, top); img.SetValue(Canvas.LeftProperty, left); } /// <summary> /// 判断是否超过纵向边界 /// </summary> /// <returns></returns> private bool IsHeightOutBounds() { double rate = st.ScaleY; if ((rate * img.Height) > bounds.Height) { return true; } return false; } /// <summary> /// 判断是否超过横向边界 /// </summary> /// <returns></returns> private bool IsWidthOutBounds() { double rate = st.ScaleX; if ((rate * img.Width) > bounds.Width) { return true; } return false; } }
调用该用户控件:
View Code
loadingImage.OriginalImage = img; loadingImage.Uri = item.Uri; loadingImage.Show();