ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C#使用Stateless和箭头控件实现状态机的控制及显示

2020-06-13 22:01:32  阅读:380  来源: 互联网

标签:控件 Point Stateless 40 Height 状态机 Width new


之前开发一个小工具,内部实现一个状态机,并显示状态机当前状态及状态间的转移过程。我使用了Stateless开源类库及一个开源自定义箭头控件。自定义箭头控件是HZHControls其中一个控件,我单独把它从源码中独立出来。主要对代码做了以下改动:

  • 添加、删除、替换了一部分注释。
  • 更改了一些内部事件触发逻辑,时间长了忘了具体改了什么,但不会影响主体功能。
  • 将外部依赖的 public static void SetGDIHigh(Graphics g) 函数移到控件当前代码中,我在原作者博客的评论下有说明。

以上涉及到的相关项目的链接如下

自定义箭头控件的代码很有学习价值,可以在其基础上扩展出其它形状的控件。使用时新建一个用户控件然后复制代码即可,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;

namespace ExtControls
{    
    public partial class  Arrow : UserControl
    {
        private Color arrowColor = Color.DarkGray;
        /// <summary>
        /// 获取设置箭头颜色
        /// </summary>
        [Description("箭头颜色"), Category("自定义")]
        public Color ArrowColor
        {
            get { return arrowColor; }
            set
            {
                arrowColor = value;
                Refresh();
            }
        }
        
        private Color? borderColor = null;
        /// <summary>
        /// 获取或设置箭头边框颜色
        /// </summary>
        [Description("箭头边框颜色,为空则无边框"), Category("自定义")]
        public Color? BorderColor
        {
            get { return borderColor; }
            set
            {
                borderColor = value;
                Refresh();
            }
        }
        
        /// <summary>
        /// 箭头方向
        /// </summary>
        private ArrowDirection direction = ArrowDirection.Right;

        /// <summary>
        /// 获取或设置箭头方向
        /// </summary>
        /// <value>The direction.</value>
        [Description("获取或设置箭头方向"), Category("自定义")]
        public ArrowDirection Direction
        {
            get { return direction; }
            set
            {
                direction = value;
                ResetMyPath();
                Refresh();
            }
        }

        private string text;
        /// <summary>
        /// 与控件关联的文本。
        /// </summary>
        [Bindable(true)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        [Localizable(true)]
        [Description("与控件关联的文本"), Category("自定义")]
        public override string Text
        {
            get
            {
                return text;
            }
            set
            {
                text = value;
                Refresh();
            }
        }
        /// <summary>
        /// 图形空间
        /// </summary>
        GraphicsPath myPath;
        /// <summary>
        /// 初始化UCArrow类的新实例。
        /// </summary>
        public Arrow()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.Selectable, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.ForeColor = Color.White;
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
            this.SizeChanged += UCArrow_NeedResetChanged;
            this.Size = new Size(100, 50);
            this.ForeColorChanged += UCArrow_NeedResetChanged;
            this.ForeColor = Color.Black;
            this.FontChanged += UCArrow_NeedResetChanged;
        }

        /// <summary>
        /// 需要重绘控件的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void UCArrow_NeedResetChanged(object sender, EventArgs e)
        {
            ResetMyPath();
        }

        /// <summary>
        /// 重置图形
        /// </summary>
        private void ResetMyPath()
        {
            Point[] ps = null;
            switch (direction)
            {
                case ArrowDirection.Left:
                    ps = new Point[] 
                    { 
                        new Point(0,this.Height/2),
                        new Point(40,0),
                        new Point(40,this.Height/4),
                        new Point(this.Width-1,this.Height/4),
                        new Point(this.Width-1,this.Height-this.Height/4),
                        new Point(40,this.Height-this.Height/4),
                        new Point(40,this.Height),
                        new Point(0,this.Height/2)
                    };
                    break;
                case ArrowDirection.Right:
                    ps = new Point[] 
                    {
                        new Point(0,this.Height/4),
                        new Point(this.Width-40,this.Height/4),
                        new Point(this.Width-40,0),
                        new Point(this.Width-1,this.Height/2),
                        new Point(this.Width-40,this.Height),
                        new Point(this.Width-40,this.Height-this.Height/4),                      
                        new Point(0,this.Height-this.Height/4),
                        new Point(0,this.Height/4)
                    };
                    break;
                case ArrowDirection.Top:
                    ps = new Point[] 
                    {
                       new Point(this.Width/2,0),
                       new Point(this.Width,40),
                       new Point(this.Width-this.Width/4,40),
                       new Point(this.Width-this.Width/4,this.Height-1),
                       new Point(this.Width/4,this.Height-1),
                       new Point(this.Width/4,40),
                       new Point(0,40),
                       new Point(this.Width/2,0),
                    };
                    break;
                case ArrowDirection.Bottom:
                    ps = new Point[] 
                    {
                       new Point(this.Width-this.Width/4,0),
                       new Point(this.Width-this.Width/4,this.Height-40),
                       new Point(this.Width,this.Height-40),
                       new Point(this.Width/2,this.Height-1),
                       new Point(0,this.Height-40),
                       new Point(this.Width/4,this.Height-40),
                       new Point(this.Width/4,0),
                       new Point(this.Width-this.Width/4,0),                      
                    };
                    break;
                case ArrowDirection.Left_Right:
                    ps = new Point[] 
                    { 
                        new Point(0,this.Height/2),
                        new Point(40,0),
                        new Point(40,this.Height/4),
                        new Point(this.Width-40,this.Height/4),
                        new Point(this.Width-40,0),
                        new Point(this.Width-1,this.Height/2),
                        new Point(this.Width-40,this.Height),
                        new Point(this.Width-40,this.Height-this.Height/4),
                        new Point(40,this.Height-this.Height/4),
                        new Point(40,this.Height),
                        new Point(0,this.Height/2),                       
                    };
                    break;
                case ArrowDirection.Top_Bottom:
                    ps = new Point[] 
                    {
                       new Point(this.Width/2,0),
                       new Point(this.Width,40),
                       new Point(this.Width-this.Width/4,40),
                       new Point(this.Width-this.Width/4,this.Height-40),
                       new Point(this.Width,this.Height-40),
                       new Point(this.Width/2,this.Height-1),
                       new Point(0,this.Height-40),
                       new Point(this.Width/4,this.Height-40),
                       new Point(this.Width/4,40),
                       new Point(0,40),
                       new Point(this.Width/2,0),                      
                    };
                    break;
            }
            myPath = new GraphicsPath();
            myPath.AddLines(ps);
            myPath.CloseAllFigures();
        }

        /// <summary>
        /// 引发Control.Paint 事件。
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            var g = e.Graphics;

            // 设置GDI高质量模式抗锯齿
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;

            g.FillPath(new SolidBrush(arrowColor), myPath);

            if (borderColor != null && borderColor != Color.Empty)
                g.DrawPath(new Pen(new SolidBrush(borderColor.Value)), myPath);
            if (!string.IsNullOrEmpty(text))
            {
                var size = g.MeasureString(Text, Font);
                g.DrawString(Text, Font, new SolidBrush(ForeColor), new PointF((this.Width - size.Width) / 2, (this.Height - size.Height) / 2));
            }
        }

        
    }

    /// <summary>
    /// 箭头方向的描述枚举
    /// </summary>
    public enum ArrowDirection
    {
        /// <summary>
        /// 向左
        /// </summary>
        Left,
        /// <summary>
        /// 向右
        /// </summary>
        Right,
        /// <summary>
        /// 向上
        /// </summary>
        Top,
        /// <summary>
        /// 向下
        /// </summary>
        Bottom,
        /// <summary>
        /// 向左向右
        /// </summary>
        Left_Right,
        /// <summary>
        /// 向上向下
        /// </summary>
        Top_Bottom
    }
}

标签:控件,Point,Stateless,40,Height,状态机,Width,new
来源: https://www.cnblogs.com/timefiles/p/CsharpStatelessArrowStateMachine.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有