wpf圖片查看器,支持滑鼠滾動縮放拖拽

来源:http://www.cnblogs.com/huangli321456/archive/2016/01/08/5113554.html
-Advertisement-
Play Games

最近項目需要,要用到一個圖片查看器,類似於windows自帶的圖片查看器那樣,滑鼠滾動可以縮放,可以拖拽圖片,於是就寫了這個簡單的圖片查看器。前臺代碼: ...


最近項目需要,要用到一個圖片查看器,類似於windows自帶的圖片查看器那樣,滑鼠滾動可以縮放,可以拖拽圖片,於是就寫了這個簡單的圖片查看器。

前臺代碼:

<Window x:Class="PictureViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        AllowDrop="True" 
        Title="圖片查看器" Height="350" Width="525" Loaded="Window_Loaded"
        SizeChanged="Window_SizeChanged" DragEnter="Window_DragEnter" Drop="Window_Drop">
    <Grid x:Name="mainGrid">
        <Grid.Resources>
            <TransformGroup x:Key="TfGroup">
                <ScaleTransform ScaleX="1" ScaleY="1"/>
                <TranslateTransform X="0" Y="0"/>
            </TransformGroup>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        
        <Button Grid.Row="0" Width="50" Height="30" Cursor="Hand" Background="Transparent" BorderThickness="0" Content="打開圖片" Click="OpenImg_Click" x:Name="OpenImg" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="20,0,0,0"/>
        <Label Content="縮放倍數:" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="130,0,0,0"/>
        <TextBox x:Name="txtMinSize" Width="40" Height="30" VerticalContentAlignment="Center" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="200,0,0,0" TextChanged="txtMinSize_TextChanged" Text="0.1"/>
        <Label Content="--" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="240,0,0,0"/>
        <TextBox x:Name="txtMaxSize" Width="40" Height="30" VerticalContentAlignment="Center" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="260,0,0,0" TextChanged="txtMaxSize_TextChanged" Text="3"/>
        <ScrollViewer x:Name="mainScrollv" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalScrollBarVisibility="Disabled"
                      VerticalScrollBarVisibility="Disabled" Cursor="SizeAll" Margin="0" Focusable="False" Grid.Row="1">
            <ContentControl MouseLeftButtonDown="ContentControl_MouseLeftButtonDown"
                            MouseLeftButtonUp="ContentControl_MouseLeftButtonUp"
                            MouseMove="ContentControl_MouseMove"
                            MouseWheel="ContentControl_MouseWheel"
                            HorizontalAlignment="Center" VerticalAlignment="Center">
                <Image x:Name="IMG" Margin="0" RenderTransform="{StaticResource TfGroup}" RenderOptions.BitmapScalingMode="NearestNeighbor"/>
                
            </ContentControl>
            
        </ScrollViewer>
    </Grid>
</Window>

 

代碼解析:

  通過一個定義一個TransformGroup,通過Key綁定到圖片控制項中,並且裡面使用ScaleTransform實現縮放(scaleX是水平方向的縮放倍數,現預設為1倍,即無縮放,scaleY同理),TranslateTransform實現平移(滑鼠拖動,X為水平方向的偏移量,Y為垂直方向的偏移量)。

  另通過一個ContentControl控制項擺放圖片控制項,併為控制項綁定各種事件(滑鼠點下、抬起、拖動、滾動),圖片控制項的RenderOptions.BitmapscalingMode="NearestNeighbor"屬性用於優化圖片變換過程,防止出現圖片移動或縮放模糊。

後臺代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace PictureViewer
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }


        private bool mouseDown;
        private Point mouseXY;
        private double min = 0.1, max = 3.0;//最小/最大放大倍數


        private void Domousemove(ContentControl img, MouseEventArgs e)
        {
            if (e.LeftButton != MouseButtonState.Pressed)
            {
                return;
            }
            var group = IMG.FindResource("TfGroup") as TransformGroup;
            var transform = group.Children[1] as TranslateTransform;
            var position = e.GetPosition(img);
            transform.X -= mouseXY.X - position.X;
            transform.Y -= mouseXY.Y - position.Y;
            mouseXY = position;
        }


        private void DowheelZoom(TransformGroup group, Point point, double delta)
        {
            var pointToContent = group.Inverse.Transform(point);
            var transform = group.Children[0] as ScaleTransform;
            if (transform.ScaleX + delta < min) return;
            if (transform.ScaleX + delta > max) return;
            transform.ScaleX += delta;
            transform.ScaleY += delta;
            var transform1 = group.Children[1] as TranslateTransform;
            transform1.X = -1 * ((pointToContent.X * transform.ScaleX) - point.X);
            transform1.Y = -1 * ((pointToContent.Y * transform.ScaleY) - point.Y);
        }


        private void ContentControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var img = sender as ContentControl;
            if (img == null)
            {
                return;
            }
            img.CaptureMouse();
            mouseDown = true;
            mouseXY = e.GetPosition(img);
        }

        private void ContentControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            var img = sender as ContentControl;
            if (img == null)
            {
                return;
            }
            img.ReleaseMouseCapture();
            mouseDown = false;
        }

        private void ContentControl_MouseMove(object sender, MouseEventArgs e)
        {
            var img = sender as ContentControl;
            if (img == null)
            {
                return;
            }
            if (mouseDown)
            {
                Domousemove(img, e);
            }
        }

        private void ContentControl_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            var img = sender as ContentControl;
            if (img == null)
            {
                return;
            }
            var point = e.GetPosition(img);
            var group = IMG.FindResource("TfGroup") as TransformGroup;
            var delta = e.Delta * 0.001;
            DowheelZoom(group, point, delta);
        }

        private void OpenImg_Click(object sender, RoutedEventArgs e)
        {
            // 在WPF中, OpenFileDialog位於Microsoft.Win32名稱空間            
            Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog();
            dialog.Filter = "Files (*.png)|*.png|Files(*.jpg)|*.jpg";
            if (dialog.ShowDialog() == true)
            {
                //MessageBox.Show(dialog.FileName);
                this.IMG.Source = new BitmapImage(new Uri(dialog.FileName));
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            setViewSize();
        }
        private void setViewSize()
        {
            mainScrollv.Width = this.ActualWidth;
            mainScrollv.Height = this.ActualHeight - 50;
        }

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            setViewSize();
        }

        private void txtMinSize_TextChanged(object sender, TextChangedEventArgs e)
        {
            this.min = double.Parse(txtMinSize.Text);
        }

        private void txtMaxSize_TextChanged(object sender, TextChangedEventArgs e)
        {
            this.max = double.Parse(txtMaxSize.Text);
        }

        private void Window_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effects = DragDropEffects.Link;//WinForm中為e.Effect = DragDropEffects.Link
            else e.Effects = DragDropEffects.None;//WinFrom中為e.Effect = DragDropEffects.None

        }

        private void Window_Drop(object sender, DragEventArgs e)
        {
            string filename = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
            this.IMG.Source = new BitmapImage(new Uri(filename));
        }


    }
}

 

可將圖片拖拽到視窗打開,Window_DragEnter里驗證拖拽進來的文件是否可用,Window_Drop處理拖拽進來之後的事情

 

源碼:http://files.cnblogs.com/files/huangli321456/PictureViewer.zip

 

代碼參照:http://www.cnblogs.com/snake-hand/archive/2012/08/13/2636227.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 【實例說明】 本例關鍵點是練習使用^的使用,沒有什麼技術含量,大牛勿噴。呵呵。。 在介紹實例之前先來剪短瞭解一下加密的概念。 加密是指通過某種特殊的方法,更改已有信息的內容,使得未授權的用戶即使得到了加密的信息,如果沒有正確解密的方法,那麼也無法得到信息的內容。 談到加密的話題,一些讀者朋友一定非常...
  • Cron Expressions——Cron 表達式按順序依次為秒(0~59)分鐘(0~59)小時(0~23)天(月)(0~31,但是你需要考慮你月的天數)月(0~11)天(星期)(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)7.年份(1970-2099)其中每個...
  • 來源:http://zxlovenet.cnblogs.com聲明:本文原創發表於博客園,作者為初行本文歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則視為侵權。從安裝到配置首先到官網http://www.nunit.org/下載如下圖的資料,安裝NUnit-2.6....
  • 主要介紹一下C#的delegate的用法以及如何實現類似javascript的each方法,並簡要說明delegate,Func, Action和 Predicate的區別
  • 前言最近在幫一家知名外企開發Universal Windows Platform的相關應用,開發過程中不由感慨:項目分為兩種,一種叫做前人栽樹後人乘涼,一種叫做前人挖坑後人遭殃。不多說了,多說又要變成月經貼了。講講MEF。MEF全稱Managed Extensibility Framework。我們...
  • 所謂條件表達式,就是分支語句,去掉分支語句咯1、分解條件表達式修改點:你有一個複雜的條件語句(就是if else語句)做法:將條件表達式的三個部分分別提煉出獨立函數即 if (A部分) { B部分; } ...
  • 說非同步前,首先講講這些概念,非同步/同步、多線程。 非同步:是指呼叫另一操作後,不等待其結果,繼續執行之後的操作,若之後沒有其他操作,當前線程將進入睡眠狀態,而CPU時間將有機會切至其他線程。在非同步操作完成後通過回調函數的方式獲取通知與結果。非同步的實現方式有多種,如多線程與完成埠。多線程將非同步操作放...
  • 在WPF中的實現和WinForm中的實現99%相似,將要實現接受拖拽釋放的控制項添加DragEnter事件和Drop事件,本例中控制項Grid grid作為接受控制項,添加事件操作如下:private void grid_Drop(object sender, DragEventArgs e){ stri...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...