小菜的系統框架界面設計-灰姑娘到白雪公主的蛻變(工具條OutLookBar)

 

灰姑娘自己也有自已的優勢,可是卻可能由於外貌不討人喜歡,要變成白雪公主卻須要有不少勇氣和決心去改變自已:canvas

  1. 有一顆善良的心
  2. 討人喜好的外貌

  20130617221355--蛻變-->  QQ圖片20130617221523app

我這裏講的是一個工具條的蛻變過程,用」灰姑娘到白雪公主蛻變」這個比喻不知道是否合理?還懇請高人討教。ide

工具條控件提供了一種相似Outlook方式的導航菜單,用來切換各類業務窗口,用上這個控件,確定爲你的程序增色很多,這個工具條的優勢是能夠上下划動,很靈活,這個是我須要採用的;工具

缺點是隻能跟傳統的系統界面進行匹配,提供外接設置的接口比較少,而且它沒有任何的換膚功能, 若是用到具備換膚功能的系統中,它真變成了「土裏土氣的灰姑娘」。網站

現狀

如今來看傳統的OutLookBar的長相,是否是有些土裏土氣眨眼?this

OutlookBarOld

蛻變後

如今我要讓它變成白雪公主,對它進行改造,添加支持換膚功能(背景色根據須要設置)...這樣就秀氣多了大聲笑, 來看它的蛻變過程,以下:spa

(1)Office2007Blue:設計

文字中間對齊,Office鼠標通過效果:3d

OutlookBarNew

文字向左對齊,Office鼠標通過效果:code

OutlookBarNew4

Office鼠標通過效果:

OutlookBarNew5

另外一種背景色,這個能夠經過設置調整:

OutlookBarNew6

鼠標點下時效果:

OutlookBarNew7

(2)Office2007Silver:

鼠標通過時效果:

OutlookBarNew2

正常狀態:

OutlookBarNew8

 

如何蛻變?

另外一種OutLook的效果,它作得很是漂亮,請參考網站 www.codeproject.com上的一篇介紹OutLook樣式的導航條的文章《A Serious Outlook Style Navigation Pane Control》,具體圖示:

buttonsBandsAndGroups

正常效果                                        鼠標通過效果                             鼠標點擊效果

buttonNormalbuttonHoveredbuttonActive

它的兩種樣式:

Office2007Blue:

Office2007Blue

Office2007Silver:

Office2003Silver

這個控件的優勢很明顯:很清新,美觀,也靈活;至於缺點,我總感受它不可以上下划動,拉動時划動距離仍是有限的,我的總感受仍是我前面提到的那種上下划動比較靈活。

因此,我根據這個控件的設計原理,對前面講到的能上下划動的工具條控件作改善。

新特性:

  1. 添加換膚接口,可以靈活擴展皮膚模板
  2. 添加鼠標通過,按下(hover,Press)導航按鈕時Office效果

 

具體設計步驟:

  1. 設計一個基本皮膚模板類:NaviColorTableOffice.cs

參考源碼:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;

namespace UtilityLibrary.Common
{
    public class NaviColorTableOffice
    {
        // General colors 
        public virtual Color DarkBorder { get { return Color.FromArgb(101, 147, 207); } }
        public virtual Color Text { get { return Color.FromArgb(21, 66, 139); } }
        public virtual Color Background { get { return Color.FromArgb(255, 255, 255); } }
        public virtual Color ShapesFront { get { return Color.FromArgb(86, 125, 177); } }

        // NaviButton Normal
        public virtual Color ButtonLight { get { return Color.FromArgb(192, 219, 255); } }
        public virtual Color ButtonDark { get { return Color.FromArgb(173, 209, 255); } }
        public virtual Color ButtonHighlightDark { get { return Color.FromArgb(196, 221, 255); } }
        public virtual Color ButtonHighlightLight { get { return Color.FromArgb(227, 239, 255); } }

        // NaviButton hovered
        public virtual Color ButtonHoveredLight { get { return Color.FromArgb(255, 230, 159); } }
        public virtual Color ButtonHoveredDark { get { return Color.FromArgb(255, 215, 103); } }
        public virtual Color ButtonHoveredHighlightDark { get { return Color.FromArgb(255, 233, 168); } }
        public virtual Color ButtonHoveredHighlightLight { get { return Color.FromArgb(255, 254, 228); } }

        // NaviButton active
        public virtual Color ButtonActiveLight { get { return Color.FromArgb(254, 225, 122); } }
        public virtual Color ButtonActiveDark { get { return Color.FromArgb(255, 171, 63); } }
        public virtual Color ButtonActiveHighlightDark { get { return Color.FromArgb(255, 188, 111); } }
        public virtual Color ButtonActiveHighlightLight { get { return Color.FromArgb(255, 217, 170); } }

        // NaviButton clicked
        public virtual Color ButtonClickedLight { get { return Color.FromArgb(255, 211, 101); } }
        public virtual Color ButtonClickedDark { get { return Color.FromArgb(251, 140, 60); } }
        public virtual Color ButtonClickedHighlightDark { get { return Color.FromArgb(255, 173, 67); } }
        public virtual Color ButtonClickedHighlightLight { get { return Color.FromArgb(255, 189, 105); } }

        // Popuped band backcolor
        public virtual Color PopupBandBackground { get { return Color.FromArgb(227, 239, 255); } }

        // Splitter
        public virtual Color SplitterDark { get { return Color.FromArgb(182, 214, 255); } }
        public virtual Color SplitterLight { get { return Color.FromArgb(255, 255, 255); } }
        public virtual Color SplitterHighlights { get { return Color.FromArgb(255, 255, 255); } }

        // Options button
        public virtual Color ButtonOptionsOuter { get { return Color.FromArgb(67, 113, 176); } }
        public virtual Color ButtonOptionsInner { get { return Color.FromArgb(255, 248, 203); } }

        // Header of band
        public virtual Color HeaderBgDark { get { return Color.FromArgb(175, 210, 255); } }
        public virtual Color HeaderBgLight { get { return Color.FromArgb(227, 239, 255); } }
        public virtual Color HeaderBgInnerBorder { get { return Color.FromArgb(255, 255, 255); } }

        // Group
        public virtual Color GroupBgLight { get { return Color.FromArgb(226, 238, 255); } }
        public virtual Color GroupBgDark { get { return Color.FromArgb(214, 232, 255); } }
        public virtual Color GroupBgHoveredLight { get { return Color.FromArgb(255, 255, 255); } }
        public virtual Color GroupBgHoveredDark { get { return Color.FromArgb(227, 239, 255); } }
        public virtual Color GroupBorderLight { get { return Color.FromArgb(173, 209, 255); } }
        public virtual Color GroupInnerBorder { get { return Color.FromArgb(255, 255, 255); } }

        // Collapse button       
        public virtual Color CollapseButtonHoveredDark { get { return Color.FromArgb(248, 194, 94); } }
        public virtual Color CollapseButtonHoveredLight { get { return Color.FromArgb(255, 255, 220); } }
        public virtual Color CollapseButtonDownDark { get { return Color.FromArgb(232, 127, 8); } }
        public virtual Color CollapseButtonDownLight { get { return Color.FromArgb(247, 217, 121); } }

        // Collapsed band
        public virtual Color BandCollapsedBg { get { return Color.FromArgb(213, 228, 242); } }
        public virtual Color BandCollapsedFocused { get { return Color.FromArgb(255, 231, 162); } }
        public virtual Color BandCollapsedClicked { get { return Color.FromArgb(251, 140, 60); } }

        // Groupview
        public virtual Color DashedLineColor { get { return Color.FromArgb(194, 194, 194); } }
    }
}

2.  再作幾個模板,繼承皮膚基本類NaviColorTableOffice

(1). Office2007Blue

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;

namespace UtilityLibrary.Common
{
    public class NaviColorTableOffice2007Blue : NaviColorTableOffice
    {
        // General colors 
        public virtual Color DarkBorder { get { return Color.FromArgb(101, 147, 207); } }
        public virtual Color Text { get { return Color.FromArgb(21, 66, 139); } }
        public virtual Color Background { get { return Color.FromArgb(255, 255, 255); } }
        public virtual Color ShapesFront { get { return Color.FromArgb(86, 125, 177); } }

        // NaviButton Normal
        public virtual Color ButtonLight { get { return Color.FromArgb(192, 219, 255); } }
        public virtual Color ButtonDark { get { return Color.FromArgb(173, 209, 255); } }
        public virtual Color ButtonHighlightDark { get { return Color.FromArgb(196, 221, 255); } }
        public virtual Color ButtonHighlightLight { get { return Color.FromArgb(227, 239, 255); } }

        // NaviButton hovered
        public virtual Color ButtonHoveredLight { get { return Color.FromArgb(255, 230, 159); } }
        public virtual Color ButtonHoveredDark { get { return Color.FromArgb(255, 215, 103); } }
        public virtual Color ButtonHoveredHighlightDark { get { return Color.FromArgb(255, 233, 168); } }
        public virtual Color ButtonHoveredHighlightLight { get { return Color.FromArgb(255, 254, 228); } }

        // NaviButton active
        public virtual Color ButtonActiveLight { get { return Color.FromArgb(254, 225, 122); } }
        public virtual Color ButtonActiveDark { get { return Color.FromArgb(255, 171, 63); } }
        public virtual Color ButtonActiveHighlightDark { get { return Color.FromArgb(255, 188, 111); } }
        public virtual Color ButtonActiveHighlightLight { get { return Color.FromArgb(255, 217, 170); } }

        // NaviButton clicked
        public virtual Color ButtonClickedLight { get { return Color.FromArgb(255, 211, 101); } }
        public virtual Color ButtonClickedDark { get { return Color.FromArgb(251, 140, 60); } }
        public virtual Color ButtonClickedHighlightDark { get { return Color.FromArgb(255, 173, 67); } }
        public virtual Color ButtonClickedHighlightLight { get { return Color.FromArgb(255, 189, 105); } }

        // Popuped band backcolor
        public virtual Color PopupBandBackground { get { return Color.FromArgb(227, 239, 255); } }

        // Splitter
        public virtual Color SplitterDark { get { return Color.FromArgb(182, 214, 255); } }
        public virtual Color SplitterLight { get { return Color.FromArgb(255, 255, 255); } }
        public virtual Color SplitterHighlights { get { return Color.FromArgb(255, 255, 255); } }

        // Options button
        public virtual Color ButtonOptionsOuter { get { return Color.FromArgb(67, 113, 176); } }
        public virtual Color ButtonOptionsInner { get { return Color.FromArgb(255, 248, 203); } }

        // Header of band
        public virtual Color HeaderBgDark { get { return Color.FromArgb(175, 210, 255); } }
        public virtual Color HeaderBgLight { get { return Color.FromArgb(227, 239, 255); } }
        public virtual Color HeaderBgInnerBorder { get { return Color.FromArgb(255, 255, 255); } }

        // Group
        public virtual Color GroupBgLight { get { return Color.FromArgb(226, 238, 255); } }
        public virtual Color GroupBgDark { get { return Color.FromArgb(214, 232, 255); } }
        public virtual Color GroupBgHoveredLight { get { return Color.FromArgb(255, 255, 255); } }
        public virtual Color GroupBgHoveredDark { get { return Color.FromArgb(227, 239, 255); } }
        public virtual Color GroupBorderLight { get { return Color.FromArgb(173, 209, 255); } }
        public virtual Color GroupInnerBorder { get { return Color.FromArgb(255, 255, 255); } }

        // Collapse button       
        public virtual Color CollapseButtonHoveredDark { get { return Color.FromArgb(248, 194, 94); } }
        public virtual Color CollapseButtonHoveredLight { get { return Color.FromArgb(255, 255, 220); } }
        public virtual Color CollapseButtonDownDark { get { return Color.FromArgb(232, 127, 8); } }
        public virtual Color CollapseButtonDownLight { get { return Color.FromArgb(247, 217, 121); } }

        // Collapsed band
        public virtual Color BandCollapsedBg { get { return Color.FromArgb(213, 228, 242); } }
        public virtual Color BandCollapsedFocused { get { return Color.FromArgb(255, 231, 162); } }
        public virtual Color BandCollapsedClicked { get { return Color.FromArgb(251, 140, 60); } }

        // Groupview
        public virtual Color DashedLineColor { get { return Color.FromArgb(194, 194, 194); } }
    }
}

(2). Office2007Silver

using System.Drawing;

namespace UtilityLibrary.Common
{
    public class NaviColorTableOffice2007Silver : NaviColorTableOffice
   {
      // General colors 
      public override Color DarkBorder { get { return Color.FromArgb(111, 112, 116); } }
      public override Color Text { get { return Color.FromArgb(21, 66, 139); } }
      public override Color ShapesFront { get { return Color.FromArgb(101, 104, 112); } }

      // NaviButton Normal
      public override Color ButtonLight { get { return Color.FromArgb(219, 222, 226); } }
      public override Color ButtonDark { get { return Color.FromArgb(197, 199, 209); } }
      public override Color ButtonHighlightDark { get { return Color.FromArgb(214, 218, 228); } }
      public override Color ButtonHighlightLight { get { return Color.FromArgb(235, 238, 250); } }

      // Header of band
      public override Color HeaderBgDark { get { return Color.FromArgb(218, 223, 230); } }
      public override Color HeaderBgLight { get { return Color.FromArgb(255, 255, 255); } }

      // Splitter
      public override Color SplitterDark { get { return Color.FromArgb(119, 118, 151); } }
      public override Color SplitterLight { get { return Color.FromArgb(168, 167, 191); } }
      public override Color SplitterHighlights { get { return Color.FromArgb(255, 255, 255); } }

      // Group
      public override Color GroupBgLight { get { return Color.FromArgb(215, 215, 229); } }
      public override Color GroupBgDark { get { return Color.FromArgb(216, 216, 230); } }
      public override Color GroupBgHoveredLight { get { return Color.FromArgb(215, 215, 229); } }
      public override Color GroupBgHoveredDark { get { return Color.FromArgb(216, 216, 230); } }
      public override Color GroupBorderLight { get { return Color.FromArgb(197, 199, 199); } }

      // Collapsed band
      public override Color BandCollapsedBg { get { return Color.FromArgb(238, 238, 244); } }

      public override Color PopupBandBackground { get { return Color.FromArgb(240, 241, 242); } }
   }
}

(3). Office2007Black

using System.Drawing;

namespace UtilityLibrary.Common
{
    public class NaviColorTableOffice2007Black : NaviColorTableOffice
   {
      // General colors 
      public override Color DarkBorder { get { return Color.FromArgb(167, 173, 182); } }
      public override Color Text { get { return Color.FromArgb(0, 0, 0); } }
      public override Color ShapesFront { get { return Color.FromArgb(49, 52, 49); } }

      // NaviButton Normal
      public override Color ButtonLight { get { return Color.FromArgb(219, 222, 226); } }
      //public override Color ButtonDark { get { return Color.FromArgb(199, 203, 209); } }
      public override Color ButtonDark { get { return Color.Silver; } }
      public override Color ButtonHighlightDark { get { return Color.FromArgb(223, 226, 228); } }
      public override Color ButtonHighlightLight { get { return Color.FromArgb(248, 248, 249); } }

      // Header of band
      public override Color HeaderBgDark { get { return Color.FromArgb(189, 193, 200); } }
      public override Color HeaderBgLight { get { return Color.FromArgb(240, 241, 242); } }

      // Splitter
      public override Color SplitterDark { get { return Color.FromArgb(195, 200, 206); } }
      public override Color SplitterLight { get { return Color.FromArgb(255, 255, 255); } }
      public override Color SplitterHighlights { get { return Color.FromArgb(255, 255, 255); } }

      // Group
      public override Color GroupBgLight { get { return Color.FromArgb(239, 240, 241); } }
      public override Color GroupBgDark { get { return Color.FromArgb(221, 224, 227); } }
      public override Color GroupBgHoveredLight { get { return Color.FromArgb(255, 255, 255); } }
      public override Color GroupBgHoveredDark { get { return Color.FromArgb(232, 234, 236); } }
      public override Color GroupBorderLight { get { return Color.FromArgb(199, 203, 209); } }
      public override Color GroupInnerBorder { get { return Color.FromArgb(255, 255, 255); } }

      // Collapsed band
      public override Color BandCollapsedBg { get { return Color.FromArgb(235, 235, 235); } }

      public override Color PopupBandBackground { get { return Color.FromArgb(240, 241, 242); } }
   }
}

(4). 如何去實現渲染這個工具欄上的按鈕,把它們加工得更漂亮一點?

我是這樣作的,設計一對控件進行渲染的類:NaviButtonRendererOffice2007.cs,由它來實現對控件進行重加工,參考以下:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace UtilityLibrary.Common
{
    public class NaviButtonRendererOffice2007
    {
        NaviColorTableOffice colorTable;
        public NaviButtonRendererOffice2007()
        {
            // Use by default the blue colors, override this with the property ColorTable
            colorTable = new NaviColorTableOffice2007Blue();
        }
        /// <summary>
        /// Gets or sets the table of colors
        /// </summary>
        public NaviColorTableOffice ColorTable
        {
            get { return colorTable; }
            set { colorTable = value; }
        }

        /// <summary>
        /// Draws the background gradients of an Button
        /// </summary>
        /// <param name="g">The graphics surface to draw on</param>
        /// <param name="bounds">The bounds that the drawing should apply to</param>
        public  void DrawBackground(Graphics g, Rectangle bounds, ControlState state, InputState inputState)
        {
            Color[] endColors = new Color[1];

            if ((state == ControlState.Normal) && (inputState == InputState.Normal))
            {
                endColors = new Color[] { ColorTable.ButtonLight, ColorTable.ButtonDark, 
                                ColorTable.ButtonHighlightDark, ColorTable.ButtonHighlightLight };
            }
            else if ((state == ControlState.Normal) && (inputState == InputState.Hovered))
            {
                endColors = new Color[] { ColorTable.ButtonHoveredLight, ColorTable.ButtonHoveredDark, 
                                ColorTable.ButtonHoveredHighlightDark, ColorTable.ButtonHoveredHighlightLight };
            }
            else if ((state == ControlState.Active) && (inputState == InputState.Normal))
            {
                endColors = new Color[] { ColorTable.ButtonActiveLight, ColorTable.ButtonActiveDark, 
                                ColorTable.ButtonActiveHighlightDark, ColorTable.ButtonActiveHighlightLight };
            }
            else if ((inputState == InputState.Clicked)
               || ((state == ControlState.Active) && (inputState == InputState.Hovered)))
            {
                endColors = new Color[] { ColorTable.ButtonClickedLight, ColorTable.ButtonClickedDark, 
                                ColorTable.ButtonClickedHighlightDark, ColorTable.ButtonClickedHighlightLight };
            }

            float[] ColorPositions = { 0.0f, 0.62f, 0.62f, 1.0f };

            ExtDrawing.DrawGradient(g, bounds, endColors, ColorPositions);

            using (Pen p = new Pen(ColorTable.DarkBorder))
            {
                g.DrawLine(p, bounds.Left, bounds.Top, bounds.Right, bounds.Top);
            }
            
        }

        /// <summary>
        /// Draws text on a graphics canvas
        /// </summary>
        /// <param name="g">The graphics surface to draw on</param>
        /// <param name="bounds">The bounds of the text</param>
        /// <param name="font">The font of the text</param>
        /// <param name="text">The text to draw</param>
        /// <param name="rightToLeft">Rigth to left or left to right layout</param>
        public  void DrawText(Graphics g, Rectangle bounds, Font font, string text, bool rightToLeft)
        {
            using (Brush brush = new SolidBrush(ColorTable.Text))
            {
                if (rightToLeft)
                {
                    TextRenderer.DrawText(g, text, font, bounds, ColorTable.Text,
                       TextFormatFlags.SingleLine | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis
                       | TextFormatFlags.Right | TextFormatFlags.RightToLeft);
                }
                else
                {
                    TextRenderer.DrawText(g, text, font, bounds, ColorTable.Text,
                       TextFormatFlags.SingleLine | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis);
                }
            }
        }
    }
}

咱們直接調DrawBackground(Graphics g, Rectangle bounds, ControlState state, InputState inputState) 對按鈕進行重繪就能夠實現了。

那麼如何達到換膚的功能?關鍵是對象NaviColorTableOffice,其餘的皮膚類都繼承它,這裏是經過多態的方式進行實例化對象。

請參考StyleManager.cs,這是一個皮膚製造工廠,經過反射機制去動態實例化皮膚對象:

using System;
using System.Collections.Generic;
using System.Text;
using UtilityLibrary.Enums;

namespace UtilityLibrary.Common
{
    class StyleManager
    {
        public static NaviColorTableOffice GetOffice2007ColorTable(Style style)
        {
            string className = "UtilityLibrary.Common.NaviColorTable" + style.ToString();
            Type type = Type.GetType(className);
            if (type != null)
            {
                return (NaviColorTableOffice)Activator.CreateInstance(type);
            }
            return null;
        }
    }
}

我添加一個enum類型做爲皮膚的樣式,這裏只設計三個樣式。

namespace UtilityLibrary.Enums
{
    public enum Style
    {
        Office2007Blue,
        Office2007Silver,
        Office2007Black
    }
}

最後關鍵的一步到了,在OutlookBar.cs實現接口IStyle:

#region OutlookBar class
    [ToolboxBitmap(typeof(UtilityLibrary.WinControls.OutlookBar), 
    "UtilityLibrary.WinControls.OutlookBar.bmp")]
    public class OutlookBar : System.Windows.Forms.Control,IStyle
    {
}

以下代碼是客戶端設置皮膚的關鍵:

#region IStyle 成員
        public void SetStyle(Style style)
        {
            rendererOffice2007.ColorTable = StyleManager.GetOffice2007ColorTable(style);
            this.Refresh();
        }

        private Style _style = Style.Office2007Blue;
        public Style Style
        {
            get
            {
                return _style;
            }
            set
            {
                _style = value;
                SetStyle(_style);
            }
        }

因此咱們在客戶端設計某個皮膚時,能夠這樣作:

OutlookBar outlookBar1 = new OutlookBar();
outlookBar1.SetStyle(Style.Office2007Blue);//設置Office2007Blue皮膚
outlookBar1.OfficeStyle = true;//設置Office效果,主要是mouse通過,點下時的效果

最終的總體效果

總結

整個過程下來,主要作的工做:

  1. 設計模板

  2. 設計換膚接口

  3. 渲染按鈕控件

  4. 換膚接口調用

通過這幾個工序,對這個灰姑娘進行「整容」,「美化」的一系列過程,它就變成了白雪公主啦,不過由於它先天不足,只能說差很少過得去。

上傳改善後的控件供你們試用吧,分享快樂吐舌笑臉,若是感受比原來的好,記得給小弟點評一下喔~~~微笑

 

下載

相關文章
相關標籤/搜索