制作簡易圖像瀏覽器

作者: %admin  來源: 博客園  發布時間: 2011-01-09 23:17  閱讀: 741 次  推薦: 2   原文鏈接   [收藏]  

  先發點牢騷放松下心情, 最近完全沒有做項目的動力,每天感覺腦子昏昏沉沉的沒有一點狀態。

  一來可能快春節了,自己離家比較遠也在擔心何時回家何時購票,

  二來公司程序員就我一個人在單干,軟件 項目什么的做好了,卻不能接受一次又一次的添加功能和修改數據庫,(我真的很想罵某個人的娘)

  三來也老早計劃好了11年4月份一年合同到期后就離職,現在好像一點都靜不下心來

  如果有各位同僚給我開解開解我也好恢復下心境。

  好了,下面來說這個簡易的圖像瀏覽器吧。  其實這也不是無中生有我要去做的一個東西, 我們公司的軟件 項目都是我一個人在做的, 在做之前我已經構思好了所有的東西,也盡自己最大努力去實現了。 但是一個人兼顧設計 開發 測試,。所有東西幾個月下來, 有時候就會有其他新的想法。

  這個圖像瀏覽器就算是其中一個小的部分吧, 先來看一下預覽效果吧,

  就是Demo有縮略圖的這個東西了, 我把它封裝成了一個控件  命名為 ImageViewBox  .其實這個東西很簡單,但是就是簡單我們有時候一下又不知道如何下手,

  再加上我本身最近心情就比較煩躁,所以實現的時候太多細節也沒注意, 只是簡單實現一個縮略圖瀏覽這樣一個效果!

  不過就具體的實現方法我還是簡單說下,也方便有需要的朋友可以借鑒!

  先簡單描述下我可能要應用的場景:


我的軟件是一套工程監測軟件, 工程會有工程圖, 一個工程會分幾部分,每部分有自己的一張CAD的工程圖,  每部分工程中會安裝很多傳感器或者監測設備。   那我所要做的軟件首先需要一個主界面,這個主界面上就需要能顯示工程圖 以及 傳感器的分布 的一個預覽效果。 在我之前有一篇博客中也提到過,以前我用剪裁圖片在原圖上進行高亮的方式來實現。  但是隨著一個工程分的部分越多,在工程背景圖上用剪裁方式就不太好了 因為會太顯擁擠!  那就只能用這樣一種瀏覽的方式,將 工程中分出來的部分 用圖像瀏覽器這種方式在顯示,當選中單擊它的時候 背景切換為它,并在它上面布設傳感器控件。 實現類似如下的效果:  

  至于上面這張圖怎么實現大家一眼也都看出來了,也不是本文要討論的! 只是為了說明這個圖片瀏覽器所要應用的一個場景,以便大家不用看到代碼后太鄙視我!好了,現在說這個圖像瀏覽器吧, 

  : 控件主體  ImageViewBox:UserControl   

  :縮略圖顯示主體  ImageViewItem:Control     這里為什么也設計為一個控件呢, 實際上是為了在 ImageViewBox中方便的直接用Dock布局,而不用復雜的繪制

  主要的東西就這2個, ImageViewItem 作為一個小控件,主要顯示圖像縮略圖和圖像標題 ,  當然為了我的特定應用場景,代碼簡單就OK了,有了ImageViewItem 只需要它添加到ImageViewBox中 并Dock =Left 就能規規矩矩的排成一行的。

   為了規矩的排成一個橫行, 我們還需要限制ImageViewBox  以及 ImageViewItem 的大小, 另外ImageViewBox 的AutoScroll 也要設置為true,剩下的工作就是ImageViewItem 的呈現了,主要的效果就是 圓角邊框、鼠標經過時的變色, 鼠標選中時的變色以及事件。原本我的應用場景中是需要定義一個對象 如: class 截面

        {
            public Bitmap 截面背景圖
            {
                
get;
                
set;
            }

            
public string 截面名稱
            {
                
get;
                
set;
            }

            
public 傳感器 傳感器數組
            {
                
get;
                
set;
            }
        }

  這樣的話,我在ImageViewItem 的構造函數傳入  截面 這個對象就可以了, 但是后來想想還是算了, 實際用到的時候用它的tag屬性來綁定,現在為了演示方便就直接 public ImageViewItem(Bitmap bmp,string title)   好了。

  然后就是定義三種狀態下,對不同狀態下 ImageViewItem的繪制了, 限定縮略圖大小為 96*96 , 具體的繪制部分代碼如下:

 /// <summary>
        /// 重寫控件繪制
        
/// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            
using(Graphics g=e.Graphics)
            {
                
//處理背景
                g.SetClip(this.ClientRectangle);
                g.Clear(SystemColors.Window);
                
//繪制邊框與背景色
                using(Pen borderPen=new Pen(NONE_BORDER_COLOR))
                {
                    
if (BackStyle == DrawBackStyle.FOCUSED)
                    {
                        borderPen.Color 
= FOCUSED_BORDER_COLOR;
                        
using (LinearGradientBrush backBrush = new LinearGradientBrush(this.ClientRectangle,FOCUSED_LIGHT_COLOR,FOCUSED_DEEP_COLOR, LinearGradientMode.Vertical))
                        {
                            g.FillPath(backBrush, Utility.GetRoundedRectanglePath(
22this.Width - 4this.Height - 45));
                        }
                    }
                    
else if (BackStyle == DrawBackStyle.SELECTED)
                    {
                        borderPen.Color 
= SELECTED_BORDER_COLOR;
                        
using (LinearGradientBrush backBrush = new LinearGradientBrush(this.ClientRectangle, SELECTED_LIGHT_COLOR, SELECTED_DEEP_COLOR, LinearGradientMode.Vertical))
                        {
                            g.FillPath(backBrush, Utility.GetRoundedRectanglePath(
22this.Width - 4this.Height - 45));
                        }
                    }
                    g.DrawPath(borderPen, Utility.GetRoundedRectanglePath(
22this.Width - 4this.Height - 45));
                }
                
//繪制縮略圖與標題
                if (this.ThumbnailImage != null)
                {
                    g.DrawImage(
this.ThumbnailImage, new Rectangle(IMAGE_POINT, IMAGE_SIZE));
                }
                Color foreColor 
= this.ImageViewBox.ForeColor;
                Rectangle rt 
= new Rectangle(310398, TextRenderer.MeasureText(this.Title, ImageViewBox.Font).Height);
                TextRenderer.DrawText(g, 
this.Title, ImageViewBox.Font, rt, foreColor,
                    TextFormatFlags.EndEllipsis 
| TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.SingleLine);
            }
        }

  有一些細節方面的東西我就不多解釋了,主要是為了方便我的應用, 不如 ImageViewItem中的  ImageViewBox 屬性等! 以及用ImageViewBox屬性來設置標題字體顏色等。這一部分對于有過制作自定義控件的朋友就很熟悉了, 那關于三種狀態的的變化呢 也很簡單,就是重寫下 OnMouse 相關的函數,代碼如下


        /// <summary>
        /// 鼠標進入控件區域
        
/// </summary>
        /// <param name="e"></param>
        protected override void OnMouseEnter(EventArgs e)
        {
            
if (!BackStyle.Equals(DrawBackStyle.SELECTED))
            {
                
this.BackStyle = DrawBackStyle.FOCUSED;
                
this.Refresh();
            }
            
base.OnMouseEnter(e);
        }

        
/// <summary>
        /// 鼠標移出控件區域
        
/// </summary>
        /// <param name="e"></param>
        protected override void OnMouseLeave(EventArgs e)
        {
            
if (!BackStyle.Equals(DrawBackStyle.SELECTED))
            {
                
this.BackStyle = DrawBackStyle.NONE;
                
this.Refresh();
            }
            
base.OnMouseLeave(e);
        }

        
/// <summary>
        /// 控件被點擊
        
/// </summary>
        /// <param name="e"></param>
        protected override void OnClick(EventArgs e)
        {
            
//取消其他ImageViewItem 選中狀態
            foreach (ImageViewItem item in this.ImageViewItemCollection)
            {
                
if (item.BackStyle != DrawBackStyle.NONE)
                {
                    item.BackStyle 
= DrawBackStyle.NONE;
                    item.Refresh();
                }
            }
            
this.BackStyle = DrawBackStyle.SELECTED;
            
this.Refresh();
            
base.OnClick(e);
        }

  有了上面這些東西,其實就已經能簡單的實現本文標題的這個東西了,不過我們還需要加點東西 ,需要加一個類ImageViewItemCollection.cs  。呵呵,這樣大家就知道該怎么做了吧,那我就不廢話了! 請不要拍我,我也知道簡單,我也想封裝好一點發出來,但是真的心煩意亂,就當是給也在找這方面實現資料的朋友一個示例吧,雖然不怎么好!

   我就直接上代碼了:代碼下載

2
0
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()