一、功能需求:
1、打开图片、打开文件夹;
2、下一张、上一张图片;
3、支持拖动、缩放、还原图片显示适当大小;
cs部分代码
1 /// <summary> 2 /// Interaction logic for ImageView.xaml 3 /// </summary> 4 public partial class ImageView : UserControl 5 { 6 public ImageView() 7 { 8 InitializeComponent(); 9 } 10 11 12 bool mouseDown = false; 13 Point prePo; 14 private void Img_MouseDown(object sender, MouseButtonEventArgs e) 15 { 16 mouseDown = true; 17 Cursor = Cursors.Hand; 18 prePo = e.GetPosition(canvas); 19 } 20 21 22 /// <summary> 23 /// 移动图片 24 /// </summary> 25 /// <param name="sender"></param> 26 /// <param name="e"></param> 27 private void Img_PreviewMouseMove(object sender, MouseEventArgs e) 28 { 29 Point currentPoint = e.GetPosition(canvas); 30 if (mouseDown) 31 { 32 double left = Canvas.GetLeft(img); 33 double top = Canvas.GetTop(img); 34 if (currentPoint.X != prePo.X) 35 Canvas.SetLeft(img, left + currentPoint.X - prePo.X); 36 if (currentPoint.Y != prePo.Y) 37 Canvas.SetTop(img, top + currentPoint.Y - prePo.Y); 38 prePo = currentPoint; 39 } 40 } 41 42 private void Img_MouseUp(object sender, MouseButtonEventArgs e) 43 { 44 mouseDown = false; 45 Cursor = Cursors.Arrow; 46 } 47 48 double scale = 1; 49 /// <summary> 50 /// 放大、缩小图片 51 /// </summary> 52 /// <param name="sender"></param> 53 /// <param name="e"></param> 54 private void Img_PreviewMouseWheel(object sender, MouseWheelEventArgs e) 55 { 56 double left = Canvas.GetLeft(img); 57 double top = Canvas.GetTop(img); 58 double preW = img.ActualWidth; 59 double preH = img.ActualHeight; 60 61 if (e.Delta > 0) 62 scale = scale + 0.01; 63 else 64 scale = scale - 0.01; 65 if (scale <= 0.01) 66 scale = 0.01; 67 img.RenderTransform = new ScaleTransform(scale, scale); 68 } 69 70 /// <summary> 71 /// 图片自适应显示 72 /// </summary> 73 /// <param name="sender"></param> 74 /// <param name="e"></param> 75 private void BtnDefault_Click(object sender, RoutedEventArgs e) 76 { 77 scale = 1; 78 img.RenderTransform = new ScaleTransform(1, 1); 79 InitImage(); 80 } 81 82 /// <summary> 83 /// 还原图片居中缩放适合尺寸显示 84 /// 当图片宽(高)大于高(宽)时,如果图片宽(高)超过显示区域宽(高)则进行缩放 85 /// 然后垂直水平居中 86 /// </summary> 87 void InitImage() 88 { 89 double areaH = canvas.ActualHeight; 90 double areaW = canvas.ActualWidth; 91 if (img.Width == 0) return; 92 if(img.Width > img.Height) 93 { 94 if (img.Width > areaW) 95 { 96 double scale = areaW / img.Width; 97 //img.RenderTransform = new ScaleTransform(scale, scale); 98 double scaleH = img.Height * scale; 99 Canvas.SetTop(img, (areaH - scaleH) / 2); 100 Canvas.SetLeft(img, 0); 101 img.Width = img.Width * scale; 102 img.Height = scaleH; 103 return; 104 } 105 Canvas.SetTop(img, (areaH - img.Height) / 2); 106 Canvas.SetLeft(img, (areaW - img.Width) / 2); 107 } 108 else 109 { 110 if (img.Height > areaH) 111 { 112 double scale = areaH / img.Height; 113 //img.RenderTransform = new ScaleTransform(scale, scale); 114 double scaleW = img.Width * scale; 115 Canvas.SetTop(img, 0); 116 Canvas.SetLeft(img, (areaW - scaleW) / 2); 117 img.Width = scaleW; 118 img.Height = img.Height * scale; 119 return; 120 } 121 Canvas.SetTop(img, (areaH - img.Height) / 2); 122 Canvas.SetLeft(img, (areaW - img.Width) / 2); 123 } 124 } 125 126 /// <summary> 127 /// 上一张 128 /// </summary> 129 /// <param name="sender"></param> 130 /// <param name="e"></param> 131 private void BtnPreview_Click(object sender, RoutedEventArgs e) 132 { 133 if (images.Count <= 0) return; 134 index = --index < 0 ? images.Count - 1 : index; 135 ChangeSelect(index); 136 } 137 138 /// <summary> 139 /// 下一张 140 /// </summary> 141 /// <param name="sender"></param> 142 /// <param name="e"></param> 143 private void BtnNext_Click(object sender, RoutedEventArgs e) 144 { 145 if (images.Count <= 0) return; 146 index = ++index >= images.Count ? 0 : index; 147 ChangeSelect(index); 148 } 149 150 /// <summary> 151 /// 打开图片 152 /// </summary> 153 /// <param name="sender"></param> 154 /// <param name="e"></param> 155 private void BtnImage_Click(object sender, RoutedEventArgs e) 156 { 157 System.Windows.Forms.OpenFileDialog fileDialog = new System.Windows.Forms.OpenFileDialog(); 158 fileDialog.Title = "请选择图片文件"; 159 fileDialog.Filter = filter; 160 fileDialog.RestoreDirectory = true; 161 if(fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 162 { 163 tbNotice.Visibility = Visibility.Collapsed; 164 if (fileDialog.FileNames.Length > 1) 165 LoadImages(fileDialog.FileNames); 166 else 167 LoadFolder(System.IO.Path.GetDirectoryName(fileDialog.FileName), fileDialog.FileName); 168 } 169 } 170 171 int index = 0; 172 string folder = null; 173 List<string> images = new List<string>(); 174 string filter = "图像文件|*.png;*.jpg;*.jpeg;*.bmp"; 175 /// <summary> 176 /// 打开文件夹 177 /// </summary> 178 /// <param name="sender"></param> 179 /// <param name="e"></param> 180 private void BtnFolder_Click(object sender, RoutedEventArgs e) 181 { 182 System.Windows.Forms.FolderBrowserDialog folderBrowser = new System.Windows.Forms.FolderBrowserDialog(); 183 folderBrowser.Description = "请选择图片目录"; 184 if (folderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK) 185 { 186 tbNotice.Visibility = Visibility.Collapsed; 187 folder = folderBrowser.SelectedPath; 188 LoadFolder(folder); 189 } 190 } 191 192 /// <summary> 193 /// 切换当前图片 194 /// </summary> 195 /// <param name="select"></param> 196 void ChangeSelect(int select) 197 { 198 if (select < 0 || images.Count < 1) 199 return; 200 if (select >= images.Count) 201 select = images.Count - 1; 202 203 string file = images[select]; 204 ChangeSelect(file); 205 } 206 207 /// <summary> 208 /// 切换当前图片 209 /// </summary> 210 /// <param name="select"></param> 211 void ChangeSelect(string select) 212 { 213 tbName.Text = System.IO.Path.GetFileName(select); 214 if (!File.Exists(select)) 215 { 216 int i = images.IndexOf(select); 217 images.Remove(select); 218 MessageBox.Show("图片丢失"); 219 if (images.Count <= 0) 220 tbNotice.Visibility = Visibility.Visible; 221 else 222 ChangeSelect(i); 223 return; 224 } 225 BitmapImage bitmap = new BitmapImage(new Uri(select)); 226 img.Source = bitmap; 227 img.Width = bitmap.PixelWidth; 228 img.Height = bitmap.Height; 229 InitImage(); 230 } 231 232 /// <summary> 233 /// 加载文件到集合中 234 /// </summary> 235 /// <param name="files"></param> 236 void LoadImages(string[] files) 237 { 238 images.Clear(); 239 images.AddRange(files); 240 index = 0; 241 ChangeSelect(index); 242 } 243 244 /// <summary> 245 /// 加载目录图片到集合中 246 /// </summary> 247 /// <param name="folder"></param> 248 /// <param name="select"></param> 249 void LoadFolder(string folder, string select = null) 250 { 251 images.Clear(); 252 string[] files = Directory.GetFiles(folder); 253 if (files == null) 254 return; 255 foreach (var item in files) 256 { 257 if (filter.Contains(System.IO.Path.GetExtension(item.ToLowerInvariant()))) 258 images.Add(item); 259 } 260 index = 0; 261 ChangeSelect(select ?? images[0]); 262 } 263 }
xaml部分代码:
<UserControl x:Class="MahAppsMetro.Demo.Views.ImageView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:MahAppsMetro.Demo.Views" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <Canvas x:Name="canvas" Background="Beige"> <Image x:Name="img" Canvas.Top="0" Canvas.Left="0" MouseDown="Img_MouseDown" PreviewMouseMove="Img_PreviewMouseMove" MouseUp="Img_MouseUp" PreviewMouseWheel="Img_PreviewMouseWheel" /> </Canvas> <TextBlock x:Name="tbNotice" Text="请选择图片" VerticalAlignment="Center" HorizontalAlignment="Center" /> <TextBlock x:Name="tbName" HorizontalAlignment="Center" Margin="20" /> <WrapPanel HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="20"> <Button x:Name="btnImage" Content="打开" Width="40" Height="20" VerticalAlignment="Bottom" Background="Transparent" BorderThickness="1" Click="BtnImage_Click" /> <Button x:Name="btnFolder" Content="文件夹" Width="40" Height="20" VerticalAlignment="Bottom" Background="Transparent" BorderThickness="1" Click="BtnFolder_Click"/> <Button x:Name="btnPreview" Content="上一张" Width="40" Height="20" VerticalAlignment="Bottom" Background="Transparent" BorderThickness="1" Click="BtnPreview_Click" /> <Button x:Name="btnDefault" Content="适应" Width="40" Height="20" VerticalAlignment="Bottom" Background="Transparent" BorderThickness="1" Click="BtnDefault_Click" Canvas.Left="378" Canvas.Bottom="20"/> <Button x:Name="btnNext" Content="下一张" Width="40" Height="20" VerticalAlignment="Bottom" Background="Transparent" BorderThickness="1" Click="BtnNext_Click" /> </WrapPanel> </Grid> </UserControl>
效果:
待解决问题:拖动后释放鼠标有时没有释放状态