版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/chinahuyong/article/details/6118908
原創企業級控件庫之圖檔浏覽控件
釋出日期:2010年12月18日星期六作者:
EricHu在上兩篇:我介紹了
原創企業級控件庫之組合查詢控件和
原創企業級控件庫之大資料量分頁控件,受到了很多朋友的支援,給了我很大的動力,在此我特表感謝。有的朋友要求把源碼提供上來,我在第一篇就講了,源碼會在我這個系列講完之後提供,大家先别着急,如果你确實需要,可以時常關注此系列,謝謝大家。其實,在系列文章中,我已把核心代碼貢獻出來了。學習有時是參考别人與實踐别人的勞動成果的過程,你光把别人的代碼拿過來用用,不研究其實質,進步很慢。
這篇我将給大家介紹:企業級控件庫之圖檔浏覽控件。
摘要
我想大家用過或聽說過ACDSee 對于圖檔浏覽的強大功能,我接下來介紹的控件與ACDSee相比,可謂是天壤之别,雖沒有其強大的功能,但用在一些常用的軟體上,提供一些常用的基本功能還是可以的。同時,我隻提供一個模子,代碼開源,你可以随便修改以滿足自己的需要。
成就别人、等于成就自己。我沒什麼要求,歡迎大家多多支援與評論,覺得不錯的,記得點選文章左下角的”關注部落格”,就這麼簡單。同時,你要用什麼好的想法,也可以與我交流,謝謝。
圖檔浏覽控件運作效果如下圖:
本控件類圖:
本控件類詳細資訊:
本控件核心代碼:
#region 公共方法
#region 增加圖檔到PictureBox:void AddImage(string fileName, bool isAsync)
/// <summary>
/// 增加要顯示的圖檔
/// </summary>
/// <param name="fileName">圖檔路徑全名</param>
/// <param name="isAsync">true:異步方式加載圖檔</param>
public void AddImage(string fileName, bool isAsync)
{
if (isAsync)//異步加載圖檔
{
//圖檔異步加載完成後的處理事件
picView.LoadCompleted += new AsyncCompletedEventHandler(picView_LoadCompleted);
//圖檔加裁時,顯示等待光标
picView.UseWaitCursor = true;
//采用異步加裁方式
picView.WaitOnLoad = false;
//開始異步加裁圖檔
picView.LoadAsync(fileName);
}
else
picView.Image = Image.FromFile(fileName);//載入圖檔
InitialImage();
}
/// <param name="img">Image</param>
public void AddImage(Image img)
if (img != null)
picView.Image = img;
InitialImage();
picView = null;
#endregion
#region 得到ImageView中的圖檔:Image GetImageInImageView()
/// 得到ImageView中的圖檔
/// <returns>Image</returns>
public Image GetImageInImageView()
if (picView.Image != null)
return picView.Image;
return null;
#region 放大、縮小、适應圖檔大小、移動圖檔、左旋轉圖檔與右旋轉圖檔
/// 放大圖檔
public void ZoomInImage()
if (picView.Width < 5000)
{
zoom(picView.Location, 1100);
CenterImage();
}
else
MessageBox.Show("對不起,不能再進行放大!","提示資訊",MessageBoxButtons.OK,MessageBoxIcon.Information);
/// 縮小圖檔
public void ZoomOutImage()
if (picView.Image.Width / picView.Width < 5 && -7 < 0)
zoom(picView.Location, 900);
MessageBox.Show("對不起,不能再進行縮小!", "提示資訊", MessageBoxButtons.OK, MessageBoxIcon.Information);
/// 适應圖檔大小
public void FitImageSize()
float r1 = (float)this.w / this.picView.Width;
float r2 = (float)this.h / this.picView.Height;
this.picView.Scale(r1, r2);
this.picView.Left = (this.PnlMain.Width - this.picView.Width) / 2;
this.picView.Top = (this.PnlMain.Height - this.picView.Height) / 2;
this.picView.Cursor = Cursors.Default;
CenterImage();
/// 移動圖檔
public void MoveImage()
mnuMy.Checked = MnuMoveImageChecked;
/// 左旋轉圖檔
public void LeftRotateImage()
picView.Image.RotateFlip(RotateFlipType.Rotate90FlipX);
picView.Refresh();
/// 右旋轉圖檔
public void RightRotateImage()
picView.Image.RotateFlip(RotateFlipType.Rotate90FlipY);
#endregion
下面給出整個控件的完整代碼及窗體調用方法:
一、控件完整代碼:
#region 版權資訊
/*---------------------------------------------------------------------*
// Copyright (C) 2010 http://www.cnblogs.com/huyong
// 版權所有。
// 項目 名稱:《Winform通用控件庫》
// 文 件 名: UcImageView.cs
// 類 全 名: DotNet.Controls.UcImageView
// 描 述: 圖像顯示控件
// 建立 時間: 2010-08-05
// 建立人資訊: [**** 姓名:胡勇 QQ:80368704 E-Mail:[email protected] *****]
*----------------------------------------------------------------------*/
#endregion
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Printing;
using DotNet.Common;
namespace DotNet.Controls
{
/// <summary>
/// 圖像顯示控件
/// UcImageView
///
/// 修改紀錄
/// 2010-11-6 胡勇 優化相關代碼。
/// 2010-8-5 胡勇 建立圖像顯示控件
///
/// <author>
/// <name>胡勇</name>
/// <QQ>80368704</QQ>
/// <Email>[email protected]</Email>
/// </author>
/// </summary>
public partial class UcImageView : UserControl
{
#region 構造函數
public UcImageView()
InitializeComponent();
//記錄PnlMain的size
panelOldSize.X = PnlMain.Width;
panelOldSize.Y = PnlMain.Height;
#region 公共變量
private Point StartP = new Point(0, 0);
private bool isMouseDown = false;
private Point panelOldSize = new Point(0, 0);
private int imgIndexBy1000 = 0;
private int keyAction = 0;
private int w, h;
#region 公共事件
[Category("圖檔浏覽"), Description("移動或漫遊圖檔的Checked事件Changed時發生。"), Browsable(true)]
public event EventHandler OnMnuMoveImageCheckedChanged;
#region 公共屬性
private bool _mnuMoveImageChecked;
/// 确定漫遊菜單項是否處于選中狀态(用于是否可以移動或漫遊圖檔)
[Category("圖檔浏覽"), Description("确定漫遊菜單項是否處于選中狀态(用于是否可以移動或漫遊圖檔)"),Browsable(false)]
public bool MnuMoveImageChecked
get
return _mnuMoveImageChecked;
set
_mnuMoveImageChecked = value;
this.mnuMy.Checked = _mnuMoveImageChecked;
private bool _mnuPrintVisible = true; //預設可見
/// 确定列印菜單項是可見還是隐藏
[Category("圖檔浏覽"), Description("确定列印菜單項是可見還是隐藏"), Browsable(true)]
public bool MnuPrintVisible
return _mnuPrintVisible;
_mnuPrintVisible = value;
this.mnuPrint.Visible = _mnuPrintVisible;
#region 私有方法
private void picView_LoadCompleted(object sender, AsyncCompletedEventArgs e)
//圖檔加載完成後,将光标恢複
picView.UseWaitCursor = false;
#region 圖檔縮放
/// 圖檔縮放
/// <param name="center">縮放中心點</param>
/// <param name="zoomIndexBy1000">縮放倍率的1000倍</param>
private void zoom(Point center, int zoomIndexBy1000)
//記錄原始的picView的Size
Point oldSize = new Point(picView.Width, picView.Height);
//實施放大(以x方向為基準計算得出y方向大小,防止多次運算誤差積累使Image和picView的尺寸不比對)
picView.Width = picView.Width * zoomIndexBy1000 / 1000;
picView.Height = picView.Width * imgIndexBy1000 / 1000;
//重新定位标定後的picView位置
picView.Left -= ((picView.Width - oldSize.X) * (center.X * 1000 / oldSize.X)) / 1000;
picView.Top -= ((picView.Height - oldSize.Y) * (center.Y * 1000 / oldSize.Y)) / 1000;
//重新設定橫向滾動條最大值和位置
if (picView.Width - PnlMain.Width > 0)
hScrollBarImageView.Visible = true;
hScrollBarImageView.Maximum = picView.Width - PnlMain.Width + vScrollBarImageView.Width + 2;
hScrollBarImageView.Value = (picView.Left >= 0 ? 0 : (-picView.Left > hScrollBarImageView.Maximum ? hScrollBarImageView.Maximum : -picView.Left));
hScrollBarImageView.Visible = false;
//重新設定縱向滾動條最大值和位置
if (picView.Height - PnlMain.Height > 0)
vScrollBarImageView.Visible = true;
vScrollBarImageView.Maximum = picView.Height - PnlMain.Height + hScrollBarImageView.Width + 2;
vScrollBarImageView.Value = (picView.Top >= 0 ? 0 : (-picView.Top > vScrollBarImageView.Maximum ? vScrollBarImageView.Maximum : -picView.Top));
vScrollBarImageView.Visible = false;
#region 圖檔加裁到PictureBox中後,對其進行初始化操作
/// 圖檔加裁到PictureBox中後,對其進行初始化操作
private void InitialImage()
ImageChange();//得到最适合顯示的圖檔尺寸
this.w = this.picView.Width;
this.h = this.picView.Height;
//設定圖檔位置
picView.Location = new Point(0, 0);
//設定圖檔初始尺寸
picView.Size = picView.Image.Size;
//設定圖檔縱橫比
imgIndexBy1000 = (picView.Image.Height * 1000) / picView.Image.Width;
//設定滾動條
hScrollBarImageView.Maximum = picView.Width - PnlMain.Width + vScrollBarImageView.Width + 2;//+ hScrollBarImageView.LargeChange
vScrollBarImageView.Maximum = picView.Height - PnlMain.Height + hScrollBarImageView.Height + 2;//+ vScrollBarImageView.LargeChange
CenterImage();
#region 居中與全屏顯示圖檔
/// 使圖檔全屏顯示
private void FullImage()
if (picView.Image.Width < picView.Width && picView.Image.Height < picView.Height)
picView.SizeMode = PictureBoxSizeMode.CenterImage;
CalculateAspectRatioAndSetDimensions();
/// 保持圖檔居中顯示
private void CenterImage()
picView.Left = PnlMain.Width / 2 - picView.Width / 2;
picView.Top = PnlMain.Height / 2 - picView.Height / 2;
#region CalculateAspectRatioAndSetDimensions
/// CalculateAspectRatioAndSetDimensions
/// <returns>double</returns>
private double CalculateAspectRatioAndSetDimensions()
double ratio;
if (picView.Image.Width > picView.Image.Height)
ratio = picView.Image.Width / picView.Image.Height;
picView.Height = Convert.ToInt16(double.Parse(picView.Width.ToString()) / ratio);
ratio = picView.Image.Height / picView.Image.Width;
picView.Width = Convert.ToInt16(double.Parse(picView.Height.ToString()) / ratio);
return ratio;
#region 用于适應圖檔大小
/// 用于适應圖檔大小
private void ImageChange()
this.picView.Height = this.picView.Image.Height;
this.picView.Width = this.picView.Image.Width;
float cx = 1;
if (this.picView.Image.Height > this.PnlMain.Height) cx =
(float)(this.PnlMain.Height - 10) / (float)this.picView.Image.Height;
this.picView.Scale(cx);
this.picView.Left = (this.PnlMain.Width - this.picView.Width) / 2;
this.picView.Top = (this.PnlMain.Height - this.picView.Height) / 2;
#region 視窗(PnlMain)尺寸改變時圖像的顯示位置控制
/************************************************************
* 視窗(PnlMain)尺寸改變時圖像的顯示位置控制
************************************************************/
private void PnlMain_Resize(object sender, EventArgs e)
//對左右的方向操作(左右)
if (picView.Width <= PnlMain.Width) //圖檔左右居中
picView.Left = (PnlMain.Width - picView.Width) / 2;
else if (picView.Left < 0 && picView.Width + picView.Left < PnlMain.Width)//圖檔靠右
picView.Left = PnlMain.Width - picView.Width;
else if (picView.Left > 0 && picView.Width + picView.Left > PnlMain.Width)//圖檔靠左
picView.Left = 0;
else//保證顯示的中心圖樣不變(左右)
picView.Left += (PnlMain.Width - panelOldSize.X) / 2;
//設定橫向滾動條最大值
hScrollBarImageView.Maximum = (picView.Width - PnlMain.Width > 0 ? picView.Width - PnlMain.Width + hScrollBarImageView.Maximum + 2 : 0);
//設定橫向滾動條Value
hScrollBarImageView.Value = (picView.Left >= 0 ? 0 : -picView.Left);
//重置舊的pannel1的Width
//對上下的方向操作(上下)
if (picView.Height <= PnlMain.Height)//圖檔上下居中
picView.Top = (PnlMain.Height - picView.Height) / 2;
else if (picView.Top < 0 && picView.Height + picView.Top < PnlMain.Height)//圖檔靠下
picView.Top = PnlMain.Height - picView.Height;
else if (picView.Top > 0 && picView.Height + picView.Top > PnlMain.Height)//圖檔靠上
picView.Top = 0;
else//保證顯示的中心圖樣不變(上下)
picView.Top += (PnlMain.Height - panelOldSize.Y) / 2;
//設定縱向滾動條最大值
vScrollBarImageView.Maximum = (picView.Height - PnlMain.Height > 0 ? picView.Height - PnlMain.Height + vScrollBarImageView.Maximum + 2 : 0);
//設定縱向滾動條Value
vScrollBarImageView.Value = (picView.Top >= 0 ? 0 : -picView.Top);
//重置舊的pannel1的Height
#region 滾動條滾動時,圖檔移動
* 滾動條滾動時,圖檔移動
private void vScrollBarImageView_ValueChanged(object sender, EventArgs e)
picView.Top = -vScrollBarImageView.Value;
private void hScrollBarImageView_ValueChanged(object sender, EventArgs e)
picView.Left = -hScrollBarImageView.Value;
#region PictureBox 滑鼠按下、滑鼠進入、松開與移動事件
private void picView_MouseDown(object sender, MouseEventArgs e)
StartP = e.Location;
isMouseDown = true;
private void picView_MouseEnter(object sender, EventArgs e)
picView.Focus();
private void picView_MouseMove(object sender, MouseEventArgs e)
if (mnuMy.Checked && isMouseDown)
this.picView.Cursor = Cursors.SizeAll;
//計算出移動後兩個滾動條應該的Value
int x = -picView.Left + StartP.X - e.X;
int y = -picView.Top + StartP.Y - e.Y;
//如果滾動條的value有效則執行操作;
if (x >= -PnlMain.Width + 10 && x <= picView.Width - 10)
if (hScrollBarImageView.Visible)
{
if (x > 0)
hScrollBarImageView.Value = x > hScrollBarImageView.Maximum ? hScrollBarImageView.Maximum : x;
picView.Left = -x - (vScrollBarImageView.Visible && x < 0 ? vScrollBarImageView.Width : 0);
}
else
picView.Left = -x;
if (y >= -PnlMain.Height + 10 && y <= picView.Height - 10)
if (vScrollBarImageView.Visible)
if (y > 0)
vScrollBarImageView.Value = y > vScrollBarImageView.Maximum ? vScrollBarImageView.Maximum : y;
picView.Top = -y - (hScrollBarImageView.Visible && y < 0 ? hScrollBarImageView.Height : 0);
picView.Top = -y;
/*****************************************************
* 給予調整滾動條調整圖檔位置
*****************************************************
計算出移動後兩個滾動條應該的Value*/
/*int w = hScrollBarImageView.Value + StartP.X -e.X;
int z = vScrollBarImageView.Value + StartP.Y -e.Y;
如果滾動條的value有效則執行操作;
否則将滾動條按不同情況拉到兩頭
if (w >= 0 && w <= hScrollBarImageView.Maximum)
hScrollBarImageView.Value = w;
hScrollBarImageView.Value = (w < 0 ? 0 : hScrollBarImageView.Maximum);
if (z >= 0 && z <= vScrollBarImageView.Maximum)
vScrollBarImageView.Value = z;
vScrollBarImageView.Value = (z < 0 ? 0 : vScrollBarImageView.Maximum);
}*/
private void picView_MouseUp(object sender, MouseEventArgs e)
isMouseDown = false;
#region 滾動滑鼠滾輪實作滑鼠縮放
* 滾動滑鼠滾輪實作滑鼠縮放
private void picView_MouseWheel(object sender, MouseEventArgs e)
switch (keyAction)
case 1:
if (e.Delta > 0 && picView.Width < 10000)
zoom(e.Location, 1100);
else if (e.Delta < 0 && picView.Image.Width / picView.Width < 5)
zoom(e.Location, 900);
CenterImage();//使圖檔居中顯示
break;
case 2:
hScrollBarImageView.Value = (hScrollBarImageView.Value - e.Delta < 0 ? 0 : (hScrollBarImageView.Value - e.Delta > hScrollBarImageView.Maximum ? hScrollBarImageView.Maximum : hScrollBarImageView.Value - e.Delta));
default:
vScrollBarImageView.Value = (vScrollBarImageView.Value - e.Delta < 0 ? 0 : (vScrollBarImageView.Value - e.Delta > vScrollBarImageView.Maximum ? vScrollBarImageView.Maximum : vScrollBarImageView.Value - e.Delta));
#region 窗體按鍵事件處理
private void UcImageView_KeyDown(object sender, KeyEventArgs e)
if (e.Control)
keyAction = 1;
else if (e.Shift)
keyAction = 2;
private void UcImageView_KeyUp(object sender, KeyEventArgs e)
keyAction = 0;
}
private void picView_KeyDown(object sender, KeyEventArgs e)
keyAction = 3;
private void picView_KeyUp(object sender, KeyEventArgs e)
#region 快捷菜單事件代碼
//放大圖檔
private void mnuZoomIn_Click(object sender, EventArgs e)
this.ZoomInImage();
//縮小圖檔
private void mnuZoomOut_Click(object sender, EventArgs e)
this.ZoomOutImage();
//适應圖檔大小
private void mnuFitSize_Click(object sender, EventArgs e)
this.FitImageSize();
//漫遊圖檔
private void mnuMy_Click(object sender, EventArgs e)
MnuMoveImageChecked = !mnuMy.Checked;
this.MoveImage();
//左旋轉圖檔
private void mnuLeftRotate_Click(object sender, EventArgs e)
this.LeftRotateImage();
//右旋轉圖檔
private void mnuRightRotate_Click(object sender, EventArgs e)
this.RightRotateImage();
#region 列印圖檔
//列印圖檔
private void mnuPrint_Click(object sender, EventArgs e)
PrintDialog printDgImageView = new PrintDialog();
/*設定紙張類型
PaperSize pg = new PaperSize("A3",297,420);
printDocImageView.DefaultPageSettings.PaperSize = pg;*/
PaperSize pg = new PaperSize("A3", 23, 33);
printDgImageView.Document = printDocImageView;
if (printDgImageView.ShowDialog() == DialogResult.OK)
try
printDocImageView.Print();
catch
//停止列印
printDocImageView.PrintController.OnEndPrint(printDocImageView, new System.Drawing.Printing.PrintEventArgs());
DialogHelper.ShowWarningMsg("對不起,沒有要列印的資料!");
private void printDocImageView_PrintPage(object sender, PrintPageEventArgs e)
this.FitImageSize();//實際尺寸
e.Graphics.DrawImage(picView.Image, picView.Location.X, picView.Location.Y, picView.Width, picView.Height);
#region 窗體事件
private void mnuMy_CheckedChanged(object sender, EventArgs e)
if (OnMnuMoveImageCheckedChanged != null)
MnuMoveImageChecked = this.mnuMy.Checked;
OnMnuMoveImageCheckedChanged(sender, EventArgs.Empty);
}
}
二、WinForm窗體調用方法完整代碼:
using System.Collections.Generic;
using System.Data;
using System.Text;
namespace DotNet.WinForm.Example
public partial class FrmUcImageView : Form
public FrmUcImageView()
private void FrmUcImageView_Shown(object sender, EventArgs e)
try
ucImageViewTest.AddImage(Image.FromFile(Application.StartupPath + "//windows7.jpg"));
catch(Exception ex)
DialogHelper.ShowErrorMsg(ex.Message);
private void btnAdd_Click(object sender, EventArgs e)
openImgDlg.Filter = "Image Files(*.jpg;*.jpeg;*.tiff;*.gif)|*.jpg;*.gpeg;*.tiff;*.gif|All files (*.*)|*.*";//圖檔檔案的類型
if (openImgDlg.ShowDialog() == DialogResult.OK)
string FileName, pathName;
pathName = openImgDlg.FileName;
FileName = FileHelper.GetName(pathName);
ucImageViewTest.AddImage(Image.FromFile(pathName));
private void btnZoomIn_Click(object sender, EventArgs e)
ucImageViewTest.ZoomInImage();
private void btnZoomOut_Click(object sender, EventArgs e)
ucImageViewTest.ZoomOutImage();
private void btnMy_Click(object sender, EventArgs e)
btnMy.Checked = ucImageViewTest.MnuMoveImageChecked = !btnMy.Checked;
ucImageViewTest.MoveImage();
private void btnFitSize_Click(object sender, EventArgs e)
ucImageViewTest.FitImageSize();
private void btnLeftRotate_Click(object sender, EventArgs e)
ucImageViewTest.LeftRotateImage();
private void btnRightRotate_Click(object sender, EventArgs e)
ucImageViewTest.RightRotateImage();
private void ucImageViewTest_OnMnuMoveImageCheckedChanged(object sender, EventArgs e)
//使ucImageViewDj中的快捷菜單中的漫遊的選中狀态與目前視窗漫遊按鈕的選中狀态保持一至
btnMy.Checked = ucImageViewTest.MnuMoveImageChecked;
private void btnExit_Click(object sender, EventArgs e)
this.Close();
}
© 2010 EricHu
原創作品,轉貼請注明作者和出處,留此資訊。
------------------------------------------------
cnBlobs:
http://www.cnblogs.com/huyong/CSDN:
http://blog.csdn.net/chinahuyong