zoukankan      html  css  js  c++  java
  • 图形开发基础(3)-实际例子

    实现的功能包含:

        1)实现一个椭圆的按钮。可居中显示一行文本。

        2)鼠标离开按钮和进入按钮时,按钮边框和背景色需要发生变化。

     实现步骤:

        1)新增一个用户控件库。

          

    public class UserButton:System.Windows.Forms.UserControl
        {
    
        }

       2)定义控件属性:

    private Color _borderColor = Color.Blue;
    
    
            /// <summary>
            /// 按钮边框色
            /// </summary>
            [System.ComponentModel.Category("Appearance")]
            [System.ComponentModel.DefaultValue(typeof(Color),"Blue")]
            public Color BorderColor { get { return _borderColor; }
                set { _borderColor = value; }
            }
    
    
            private Color _backColor = Color.White;
    
    
            /// <summary>
            /// 按钮背景色
            /// </summary>
            [System.ComponentModel.Category("Appearance")]
            [System.ComponentModel.DefaultValue(typeof(Color), "White")]
            public Color BackColor
            {
                get { return _backColor; }
                set { _backColor = value; }
            }
    
    
    
            private Color _hoverBorderColor = Color.Red;
    
    
            /// <summary>
            /// 鼠标悬停在按钮上方时的边框色
            /// </summary>
            [System.ComponentModel.Category("Appearance")]
            [System.ComponentModel.DefaultValue(typeof(Color), "Red")]
            public Color HoverBorderColor 
            {
                get { return _hoverBorderColor; }
                set { _hoverBorderColor = value; }
            }
    
    
            private Color _hoverBackColor = Color.RoyalBlue;
    
    
            /// <summary>
            /// 按钮背景色
            /// </summary>
            [System.ComponentModel.Category("Appearance")]
            [System.ComponentModel.DefaultValue(typeof(Color), "RoyalBlue")]
            public Color HoverBackColor
            {
                get { return _hoverBackColor; }
                set { _hoverBackColor = value; }
            }
    
            private string _caption = string.Empty;
    
    
            /// <summary>
            /// 按钮文本
            /// </summary>
            [System.ComponentModel.Category("Appearance")]
            [System.ComponentModel.DefaultValue(null)]
            public string Caption
            {
                get { return _caption; }
                set { _caption = value; }
            }
    
            /// <summary>
            /// 鼠标悬停标志
            /// </summary>
            private bool bMouseHoverFlag = false;

    3)添加相关事件

        开发自定义控件可以绑定控件的Paint事件,也可以重写OnPaint方法。在重写OnPaint方法时一定要调用base.OnPaint方法。

        OnPaint方法中,PaintEventArgs属性包含Graphics和ClipRectangle属性。Graphics可以看作需要绘制的画布,ClipRectangle是绘制区域剪切矩形。一般情况下,控件重新绘制内容时不需要重写所有的内容,而是绘制一部分内容。该参数指明控件中哪个部分是需要重新绘制的。该区域以外的界面不需要重新绘制,因此剪切矩形是优化图形界面软件性能的基础。

    /// <summary>
            /// 
            /// </summary>
            /// <param name="e"></param>
            protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
            {
                base.OnPaint(e);
    
                using (System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath())
                {
                    path.AddEllipse(0,0,this.ClientSize.Width-1,this.ClientSize.Height-1);
                    if (bMouseHoverFlag)
                    {
                        //绘制背景
                        using (SolidBrush b = new SolidBrush(this.HoverBackColor))
                        {
                            e.Graphics.FillPath(b, path);
                        }
                        //绘制边框
                        using (Pen p = new Pen(this.HoverBorderColor))
                        {
                            e.Graphics.DrawPath(p, path);
                        }
                    }
                    else {
    
                        //绘制背景
                        using (SolidBrush b = new SolidBrush(this.BackColor))
                        {
                            e.Graphics.FillPath(b, path);
                        }
                        //绘制边框
                        using (Pen p = new Pen(this.BorderColor))
                        {
                            e.Graphics.DrawPath(p, path);
                        }
                    }
                    if (this.Caption != string.Empty)
                    {
                        using (StringFormat f = new StringFormat())
                        {
                            f.Alignment = System.Drawing.StringAlignment.Center;
                            f.LineAlignment = System.Drawing.StringAlignment.Center;
                            f.FormatFlags = System.Drawing.StringFormatFlags.NoWrap;
                            using (SolidBrush b = new SolidBrush(this.ForeColor))
                            {
                                e.Graphics.DrawString(this.Caption,this.Font,b,new RectangleF(0,0,this.ClientSize.Width,this.ClientSize.Height),f);
                            }
    
                        }
                    }
                
                }
            }

     关于ClientSize:称为控件的客户区域。控件区域包含两部分内容:客户区和非客户区。一般开发人员绘制的界面都在客户区域,处理客户区的鼠标事件,操作系统绘制的区域在非客户区,处理非客户区的鼠标事件。当控件不存在非客户区时如没有边框和滚动条时,客户区与非客户区同。

    4)添加效果:

        在用户控件中,界面区域是矩形的,而我们绘制的按钮是椭圆形的,因此客户区域的有些部分不属于椭圆形区域。当鼠标在客户区域时,要判断鼠标是否在椭圆形区域内,否则按钮动态效果大大折扣。我们需要编写一个判断鼠标在椭圆形区域的函数。

       

     /// <summary>
            /// 检测释放鼠标悬停状态是否发生改变,若发生改变则重绘
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            private bool CheckMouseHover(int x, int y)
            {
                bool flag = false;
                using (System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath())
                {
                    path.AddEllipse(0, 0, this.ClientSize.Width - 1, this.ClientSize.Height - 1);
                    flag = path.IsVisible(x,y);
                    if (flag != bMouseHoverFlag)
                    {
                        bMouseHoverFlag = flag;
                        this.Invalidate();
                    }
                }
                return flag;
            }

      

    控件重绘有两个方法可以Invalidate,Refresh调用。Invalidate与Refresh的区别是向操作系统声明控件用户界面一部分货全部无效。但不会导致立即重绘而是延迟一段时间后才开始重绘界面,是一种异步操作,这个等待时间根据操作系统繁忙程度而定,而Refresh会立即重绘整个用户界面,是一种同步操作。
  • 相关阅读:
    python常见错误
    接口自动化常用断言方法python
    Mysql2docx自动生成数据库说明文档
    常用的实用小工具
    移动App专项测试
    AndroidStudio 快捷键(最实用的20个)(转)
    Linux常用命令大全(非常全!!!)(转)
    Fiddler使用教程(转)
    Subversion Edge
    杂点
  • 原文地址:https://www.cnblogs.com/fer-team/p/4352193.html
Copyright © 2011-2022 走看看