- 积分
 - 40186
 
- 好友
  
- 记录
  
- 主题
  
- 帖子
  
- 听众
  
- 收听
  
 
 
 
 
 
 | 
 
      C#皮肤-ContextMenuStrip 控件实现 
 
导读部分 
------------------------------------------------------------------------------------------------------------- 
C#皮肤-实现原理系列文章导航  
http://www.sufeinet.com/thread-2-1-1.html 
 
看看效果先
  
 这个控件是在系统控件ContextMenuStrip的基础之上来实现的,其实就是一个快捷菜单,也可以当成是左键菜单 来使用,具本的用户看文章最好面的详细介绍,我们先来看一下实现后的效果 
1.当成下拉和快捷菜单使用时的效果 
 
      
 
 
2.当成右键菜单使用时效果 
 
     
 
   
来看看实现 
 
 我们先来看看实现 的情况 吧, 
我们第一步要打开我们的项目,然后右击项目,新添加一个Component组件。然后继承一下ContextMenuStrip类  
 代码如下 
[code=csharp]public class ContextMenuStrip : System.Windows.Forms.ContextMenuStrip[/code] 
接来来一步我们来设置一下这个快捷菜单 吧 
[code=csharp]//可以使用一个图标来表示控件 ContextMenuStrip快捷菜单   
    [ToolboxBitmap(typeof(System.Windows.Forms.ContextMenuStrip))][/code] 
我们来看一下两个基本的构造器是怎么来实现 的吧,多说没有用,代码很简单一起来看一下吧 
[code=csharp]//构造器 
        public ContextMenuStrip() 
            : base() 
        { 
            this.SetStyle(ControlStyles.UserPaint, true); 
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
            this.SetStyle(ControlStyles.DoubleBuffer, true); 
            this.SetStyle(ControlStyles.ResizeRedraw, true); 
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); 
 
            //Office格式颜色 
            ProfessionalColorTable ColorTable = new ProfessionalColorTable(); 
            ColorTable.UseSystemColors = true; 
            //是否为设计模式 
            if (!DesignMode) 
            { 
                this.Renderer = new ToolStripRenderer(ColorTable); 
            } 
            else 
            { 
                this.Renderer = new ToolStripProfessionalRenderer(ColorTable); 
            } 
            this.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; 
            this.Font = new Font(this.Font.FontFamily, 10); 
        } 
 
        public ContextMenuStrip(IContainer container) 
            : base(container) 
        { 
            this.SetStyle(ControlStyles.UserPaint, true); 
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
            this.SetStyle(ControlStyles.DoubleBuffer, true); 
            this.SetStyle(ControlStyles.ResizeRedraw, true); 
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); 
            ProfessionalColorTable ColorTable = new ProfessionalColorTable(); 
            ColorTable.UseSystemColors = true; 
            if (!DesignMode) 
            { 
                this.Renderer = new ToolStripRenderer(ColorTable); 
            } 
            else 
            { 
                this.Renderer = new ToolStripProfessionalRenderer(ColorTable); 
            } 
            this.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; 
            this.Font = new Font(this.Font.FontFamily, 10); 
        }[/code] 
 
大家可以看到我在构造的时候预设了一些东东哦,呵呵,可以打开皮肤的源代码查看一下,或是单步调试一下看看效果 
再来得写一下重写OnCreateControl()方法 
[code=csharp]/// <summary> 
        /// 重写OnCreateControl 
        /// </summary> 
        protected override void OnCreateControl() 
        { 
            base.OnCreateControl(); 
 
            if (!DesignMode) 
            { 
                int Rgn = Win32.CreateRoundRectRgn(1, 1, ClientSize.Width , Height , 7, 7); 
                Win32.SetWindowRgn(this.Handle, Rgn, true); 
            } 
 
            int result = Win32.SetClassLong(this.Handle, Win32.GCL_STYLE, 0); 
        } 
[/code] 
为了更好的打配我们的皮肤和效果我们得重写一下重写OnPaint事件 
[code=csharp]/// <summary> 
        /// 重写OnPaint事件 
        /// </summary> 
        /// <param name="e"></param> 
        protected override void OnPaint(PaintEventArgs e) 
        { 
            if (!DesignMode) 
            { 
                Graphics g = e.Graphics; 
 
                SolidBrush bruch = new SolidBrush(Shared.MainForm.MainFormBackGroundColor); 
                 
                g.FillRectangle(bruch, 0, 0, 25, this.Height); 
 
                bruch = new SolidBrush(Color.White); 
                g.FillRectangle(bruch, 27, 0, this.Width - 27, this.Height); 
 
                Pen pen = new Pen(Shared.MainForm.MainFormBackGroundColor2, 1f); 
                e.Graphics.DrawPath(pen, CreateRoundedRectanglePath(new Rectangle(1, 1, ClientSize.Width-3, Height-3), 5)); 
            } 
 
            base.OnPaint(e); 
 
        }[/code] 
这里面用到的CreateRoundedRectanglePath()方法代码如下,大家知道GraphicsPath是代表的一系统列的相互连接在一起的直线或 是曲线。处理的方式代码如下所示 
[code=csharp]/// <summary> 
        /// CreateRoundedRectanglePath 
        /// </summary> 
        /// <param name="rect">Rectangle</param> 
        /// <param name="cornerRadius"int></param> 
        /// <returns></returns> 
        internal static GraphicsPath CreateRoundedRectanglePath(Rectangle rect, int cornerRadius) 
        { 
            GraphicsPath roundedRect = new GraphicsPath(); 
            roundedRect.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90); 
            roundedRect.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y); 
            roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90); 
            roundedRect.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height - cornerRadius * 2); 
            roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90); 
            roundedRect.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom); 
            roundedRect.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90); 
            roundedRect.AddLine(rect.X, rect.Bottom - cornerRadius * 2, rect.X, rect.Y + cornerRadius * 2); 
            roundedRect.CloseFigure(); 
            return roundedRect; 
        } [/code] 
 
代码不是很多,有兴趣的可以调试看一下 
 
下面我主要来说一下用做快捷菜单和右键菜单时的使用方法 
 第一种是当成右键菜单  
    当我们把皮肤的源代码放入自己的项目里时,只要生成一下就会在工具箱里出现一个名为CRD.WinUI组件的选项卡,下面有这样一系统的控件 
 
 
 
我们所看到的当前选中的就是ContextMenuStrip 控件,我们只 要把他拉到我们的窗体或是用户控件上就OK了,使用方法和系统的是一样的,找到要使用这个菜单的控件在控件的ContextMenuStrip属性选择拉过来的控件就行了。 
 
第二种是当成快捷菜单来使用也就是下拉菜单的形式来使用 
  我就是我们的皮肤主窗体里标题栏上的菜单与这个配合使用的方法来看看吧 
我们先是要看控件拉到主窗体之上,然后把控件的对象指定给主窗体的this.SkinContextMenuStrip1属性就可以了,具体this.SkinContextMenuStrip1和上面的菜单 是怎么配合的这个就大家参考主窗体的实现或是直接去看源代码 
代码如下 
[code=csharp]//指定菜单 
            this.SkinContextMenuStrip1 = contextMenuStrip2;[/code] 
 |   
 
 
 
 |