• 小菜的系统框架界面设计-灰姑娘到白雪公主的蜕变(工具条OutLookBar)


     

    灰姑娘本身也有自已的优点,但是却可能因为外貌不讨人喜欢,要变成白雪公主却需要有很多勇气和决心去改变自已:

    1. 有一颗善良的心
    2. 讨人喜爱的外貌

      20130617221355--蜕变-->  QQ图片20130617221523

    我这里讲的是一个工具条的蜕变过程,用”灰姑娘到白雪公主蜕变”这个比喻不知道是否合理?还恳请高人讨教。

    工具条控件提供了一种类似Outlook方式的导航菜单,用来切换各种业务窗口,用上这个控件,肯定为你的程序增色不少,这个工具条的优点是可以上下划动,很灵活,这个是我需要采用的;

    缺点是只能跟传统的系统界面进行匹配,提供外接设置的接口比较少,并且它没有任何的换肤功能, 如果用到具有换肤功能的系统中,它真变成了“土里土气的灰姑娘”。

    现状

    现在来看传统的OutLookBar的长相,是不是有些土里土气眨眼?

    OutlookBarOld

    蜕变后

    现在我要让它变成白雪公主,对它进行改造,添加支持换肤功能(背景色根据需要设置)...这样就秀气多了大声笑, 来看它的蜕变过程,如下:

    (1)Office2007Blue:

    文字中间对齐,Office鼠标经过效果:

    OutlookBarNew

    文字向左对齐,Office鼠标经过效果:

    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. 换肤接口调用

    经过这几个工序,对这个灰姑娘进行“整容”,“美化”的一系列过程,它就变成了白雪公主啦,不过因为它先天不足,只能说差不多过得去。

    上传改善后的控件供大家试用吧,分享快乐吐舌笑脸,如果感觉比原来的好,记得给小弟点评一下喔~~~微笑

    下载

  • 相关阅读:
    模拟+位运算 HDOJ 5491 The Next
    树状数组+二分||线段树 HDOJ 5493 Queue
    线段树(区间合并) HDOJ 3308 LCIS
    双端队列 HDOJ 3530 Subsequence
    BFS HDOJ 1242 Rescue
    Codeforces Round #321 (Div. 2)
    区间专题
    递推DP HDOJ 5459 Jesus Is Here
    补题列表2
    引用与指针的异同-基础篇
  • 原文地址:https://www.cnblogs.com/aganqin/p/3140682.html
Copyright © 2020-2023  润新知