WPF 图片查看器






4.91/5 (20投票s)
学习如何在 Expression Blend 中创建 WPF 图像查看器。
引言
在本教程中,我将向您展示如何在 Expression Blend 中创建 WPF 图像查看器。完成后,该应用程序(希望)将如下所示:。
背景
该应用程序将具有一些基本功能,允许用户平移和缩放图像。缩放将通过滚动鼠标滚轮来实现。应用程序中的按钮是自定义按钮,您需要使用 VS2008 图像库。
设计
让我们开始设计应用程序的用户界面。启动 Expression Blend 并创建一个名为“Image Viewer”的新 WPF 应用程序项目。确保在 Language(语言)组合框中将语言设置为Visual Basic。
- 在“Objects and Timeline”(对象和时间线)中选择 Window 元素。在 Properties(属性)面板的 Brushes(画笔)部分选择 Background(背景),并将背景设置为渐变画笔。将第一个渐变停止设置为白色,第二个设置为浅灰色。
- 从工具箱中选择 canvas 工具。在
LayoutRoot
中绘制一个画布。 - 在 Properties(属性)面板的 Layout(布局)部分,将画布的 top(顶部)、left(左侧)和 right(右侧)边距设置为 15,bottom(底部)边距设置为 60。
- 在 Properties(属性)面板的 Appearance(外观)部分,单击 Advanced Properties(高级属性)按钮。勾选 ClipToBounds 复选框。
- 将画布重命名为“
ImgCanvas
”。 - 选择 Assets(资产)面板,在搜索框中键入“content”。您将看到几个工具。选择
ContentControl
工具。 - 在
ImgCanvas
中绘制一个ContentControl
。如果需要,使用调整大小句柄将其设置为适合画布边缘到边缘。(打开对齐辅助线捕捉,以便ContentControl
的边缘捕捉到画布的边缘。) - 将
ContentControl
重命名为“ImgContentCtrl
”,然后在 Properties(属性)面板的 Common Properties(通用属性)部分,删除Content
属性中的文本。 - 在 Layout(布局)部分,将
ImgContentCtrl
的Left
(左)和Top
(上)属性设置为零。 - 从工具箱中选择 Grid(网格)工具,并在
ImgContentCtrl
中绘制一个网格。将网格的边缘设置为与ContentControl
的边缘完全匹配。 - 将网格重命名为“
ImgGrid
”。 - 在 Assets(资产)面板的搜索框中键入“image”。仍然选中
ImgGrid
,双击Image
工具将一个图像对象添加到ImgGrid
。 - 在“Objects and Timeline”(对象和时间线)中右键单击
Image
对象,然后从上下文菜单中选择 Auto Size > Fill(自动大小 > 填充)。 - 将
Image
对象重命名为“ImgObject
”。 - 在 Assets(资产)面板的搜索框中键入“thumb”。您将看到几个工具。双击
Thumb
工具将其添加到ImgGrid
。(ImgGrid
必须是活动的内容控件。活动的内容控件有一个蓝色边框。) - 将 thumb 控件重命名为“
ImgThumb
”。右键单击ImgThumb
并从上下文菜单中选择 Auto Size > Fill(自动大小 > 填充)。 - 在 Properties(属性)面板的 Appearance(外观)部分,将
ImgThumb
的 opacity(不透明度)设置为零。
设计工作已接近完成,但我们需要添加一些按钮控件。我们将创建两个自定义按钮,一个用于显示“打开文件”对话框,另一个用于在缩放操作后使图像可全屏查看。我更喜欢在 Expression Design 中设计自定义按钮,但在本例中,为了方便起见,我们将使用 VS2008 图像库中的一些图像。我将特别使用位于“C:\Program Files\Microsoft Visual Studio 9.0\Common7\VS2008ImageLibrary\1033\VS2008ImageLibrary\Objects\png_format\WinVista”路径中的一些图像。
让我们设计自定义按钮
- 在“Objects and Timeline”(对象和时间线)中选择
LayoutRoot
,使其成为活动控件。 - 从工具箱中选择
Grid
工具,并在LayoutRoot
的左下角附近绘制一个网格。我将我的网格设置为宽度 40,高度 36。顶部和右侧边距为零,左侧边距为 34,底部边距为 8。 - 在选中新网格的情况下,在 Assets(资产)面板的搜索框中键入“image”。双击 Image 工具将一个图像对象添加到新网格中。
- 在 Properties(属性)面板的 Common Properties(通用属性)部分,单击 Source 属性组合框旁边的带省略号的按钮。这将打开“Add Existing Item”(添加现有项)对话框。导航并打开位于“C:\Program Files\Microsoft Visual Studio 9.0\Common7\VS2008ImageLibrary\1033\VS2008ImageLibrary\Objects\png_format\WinVista”路径下的名为 Folder_Open 的文件。
- 在“Objects and Timeline”(对象和时间线)中右键单击新网格,然后从上下文菜单中选择 Make Into Control(制作为控件)。在出现的“Make Into Control”(制作为控件)对话框中,选择 button(按钮)控件(它是默认选项),然后单击 OK(确定)。
- 单击 OK(确定)后,将打开自定义按钮的模板。在“Objects and Timeline”(对象和时间线)中选择
ContentPresenter
。在 Properties(属性)面板的 Common Properties(通用属性)部分,删除Content
属性中的文本。
接下来,我们将为自定义按钮添加动画,使其在 Mouse_Over
事件期间大小略微增大。
- 在“Objects and Timeline”(对象和时间线)中单击 **New**(新建)按钮(New(新建)按钮是带加号的那个)。
- 在出现的对话框中单击 OK(确定)以创建具有默认名称
Storyboard1
的新时间线。 - 在“Objects and Timeline”(对象和时间线)中选择网格元素,然后将播放头拖到 5 毫秒。
- 按住 Shift + Alt,并使用网格元素的大小调整手柄,通过向外拖动来略微增大网格的大小。
- 在“Objects and Timeline”(对象和时间线)面板中,单击“New”(新建)按钮旁边的下拉箭头,然后从上下文菜单中选择 Duplicate(复制)。将创建一个
Storyboard1
的副本Storyboard_Copy1
,并将其打开。 - 在“Objects and Timeline”(对象和时间线)中,单击“New”(新建)按钮旁边的下拉箭头,然后从上下文菜单中选择 Reverse(反转)。
- 在“Objects and Timeline”(对象和时间线)中,单击 Close Storyboard(关闭时间线)按钮。
- 选择 **Triggers**(触发器)面板,然后选择
IsMouseOver
属性触发器。 - 在 Actions when activating(激活时操作)部分单击 Add new action(添加新操作)按钮。将
Storyboard1
设置为默认操作开始。 - 在 Action when deactivating(停用时操作)部分单击 Add new action(添加新操作)按钮。将
Storyboard1
设置为默认操作开始。单击第一个组合框的下拉箭头,然后选择 Storyboard_Copy1。 - 在“Objects and Timeline”(对象和时间线)中单击 Scope Up(向上作用域)按钮,退出编辑模板模式。
- 将按钮重命名为“
OpenButton
”。 - 在仍然选中
OpenButton
的情况下,将新按钮复制并粘贴到 Window 元素上。新按钮粘贴在第一个按钮的上方。使用右箭头键将其推到第一个按钮的右侧。 - 将新按钮重命名为“
BestFitButton
”。 - 右键单击
BestFitButton
,然后从上下文菜单中选择 Edit Template > Edit a Copy(编辑模板 > 编辑副本)。在出现的对话框中单击 OK(确定)以打开按钮的模板。 - 在“Objects and Timeline”(对象和时间线)中,选择图像对象,然后在 Properties(属性)面板的 Common Properties(通用属性)部分单击
Source
属性组合框旁边的省略号按钮。 - 在“Add Existing Item”(添加现有项)对话框中,导航到“C:\Program Files\Microsoft Visual Studio 9.0\Common7\VS2008ImageLibrary\1033\VS2008ImageLibrary\Objects\png_format\WinVista”文件夹,然后打开名为“generic_picture" 的文件。
- 单击 Scope Up(向上作用域)按钮以退出编辑模板模式。
- 在 Properties(属性)面板的 Common Properties(通用属性)部分,将
OpenButton
的Tooltip
(工具提示)属性设置为“Open File'(打开文件),将BestFitButton
的Tooltip
(工具提示)属性设置为“Best Fit'(最佳匹配)。
设计工作终于完成了。接下来是编码,所以如果您还没有这样做,请保存您的工作。
编码
接下来,我们将添加代码以允许用户打开图像文件、在光标位置对图像进行缩放(放大和缩小)、平移图像,并在缩放操作后将图像恢复到合适的视图。
- 选择 **Project**(项目)面板,然后展开 MainWindow.xaml。双击 MainWindow.xaml.vb 以在 Blend 的代码编辑器中打开它。
- 添加以下代码
- 接下来,我们将添加代码以启用平移。切换回设计窗口,并在“Objects and Timeline”(对象和时间线)面板中选择
ImgThumb
。 - 单击 Properties(属性)面板中的 Events(事件)按钮以显示
Thumb
控件的事件。 - 在
DragDelta
事件文本框中键入“ImgThumb_DragDelta”,然后按 Enter。 - 在
ImgThumb
的DragDelta
事件处理程序中,键入以下代码 - 前面的代码处理平移操作,所以让我们添加缩放代码。切换回设计器窗口,滚动
ImgThumb
的事件以找到MouseWheel
事件。在MouseWheel
事件文本框中键入“ImgThumb_MouseWheel”,然后按 Enter。 - 在
ImgThumb
的MouseWheel
事件处理程序中键入以下代码
' Create a ScaleTransform object
Private myScale as New ScaleTransform
Public Sub New()
Me.InitializeComponent()
' Set the ContentControl's RenderTransform property
ImgContentCtrl.RenderTransform = myScale
End Sub
Dim left as Double = Canvas.GetLeft(ImgContentCtrl)
Dim top as Double = Canvas.GetTop(ImgContentCtrl)
Canvas.SetLeft(ImgContentCtrl, (left + e.HorizontalChange))
Canvas.SetTop(ImgContentCtrl, (top + e.VerticalChange))
' Variable for holding the mouse's delta value.
Dim deltaValue as Integer
deltaValue = e.Delta
' Set the center point of the ScaleTransform object
' to the cursor location.
myScale.CenterX = e.GetPosition(ImgContentCtrl).X
myScale.CenterY = e.GetPosition(ImgContentCtrl).Y
' Zoom in when the user scrolls the mouse wheel up
' and vice versa.
If deltaValue > 0 Then
' Limit zoom-in to 500%
If myScale.ScaleX < 5 Then
' Zoom-in in 10% increments
myScale.ScaleX += 0.1
myScale.ScaleY += 0.1
End If
' When mouse wheel is scrolled down...
Else
' Limit zoom-out to 80%
If myScale.ScaleX > 0.8 Then
' Zoom-out by 10%
myScale.ScaleX -= 0.1
myScale.ScaleY -= 0.1
End If
End If
这样就完成了缩放和平移。接下来,我们将添加打开图像文件以及在缩放或平移后将图像恢复到全屏视图的代码。
- 切换回设计窗口,并在“Objects and Timeline”(对象和时间线)中选择
OpenButton
。 - 在 Properties(属性)面板中,找到
Click
(单击)事件(它在顶部,所以向上滚动),然后在Click
(单击)事件文本框中键入“OpenButton_Click'。按 Enter。 - 在类声明之前键入以下代码
- 在
OpenButton
的Click
(单击)事件处理程序中,键入以下代码 - 切换回设计窗口并选择
BestFitButton
。在 Properties(属性)面板的Click
(单击)事件文本框中键入“BestFitButton_Click',然后按 Enter。 - 在
BestFitButton
的Click
(单击)事件处理程序中键入以下代码 - 在
BestFitButton
和OpenButton
的Click
(单击)事件处理程序中调用的BestFit()
方法会将图像设置为适合画布的大小,使其在缩放或滚动操作后完全可见。在 Blend 的代码编辑器中键入以下代码
Imports Microsoft.Win32
Dim OpenDialog as New OpenFileDialog
With OpenDialog
.Filter = "Image Files (*.jpeg)|*.jpg|All Files (*.*)|*.*"
.Title = "Open Image File"
End With
OpenDialog.ShowDialog()
If OpenDialog.FileName <> String.Empty Then
Dim newImage As New BitmapImage()
newImage.BeginInit()
newImage.UriSource New Uri(OpenDialog.FileName, UriKind.RelativeOrAbsolute)
newImage.EndInit()
' Load image file into Image Control
ImgObject.Source = newImage
End If
' Set the view of the ContentControl to a
' suitable scale and centered.
BestFit()
BestFit()
Private Sub BestFit()
' Set the scale of the ContentControl
' to 100%.
myScale.ScaleX = 1
myScale.ScaleY = 1
' Set the position of the ContentControl
' so that the image is centered.
Canvas.SetLeft(ImgContentCtrl, 0)
Canvas.SetTop(ImgContentCtrl, 0)
End Sub
您现在可以运行项目并打开一个图像文件。尝试缩放和平移。如果出现任何错误,请检查您的代码。请注意,当您最大化窗口时,图像不会居中。要解决此问题,请停止项目(如果仍在运行)。右键单击 ImgCanvas
并选择 GroupInto > ViewBox(分组到 > ViewBox)。再次运行项目,并在打开图像文件后,最大化窗口。
结论
图像查看器应用程序没有滚动条,但您可以通过将 ImgCanvas
分组到 ScrollViewer
中,并在放大时增加 ImgCanvas
的大小来添加滚动条。您需要尝试调整代码才能使其完美运行,但我认为当前的实现是合适的。希望这篇文章有所帮助。感谢阅读。
历史
- 2010 年 7 月 21 日:初次发布。