Winform实战(模仿篇)

开发工具:virsual studio 2022   +  .net8

C#和java相比各有千秋:

1.C#支持ushort无符号,java都是有符号

2.int等基本数据类型都是一个对象,内部有很多工具方法带来很多转换类型上的遍历,但底层本身还是int基本数据类型(都是语法糖),推测struct修饰的对象都是语法糖?最终都是值类型数据

3.泛型原理上,c#更加高性能,使用了占位符;而java底层还是object强转,只保证了安全性

4.C#委托等技巧上,更加高级(可能用到指针之类)click.event += eventListener;

5.支持ref和out, C#和java本事属于值传递,直接赋值临时对象的引用会变;但C#支持ref和out,就变得也支持引用传递

6.C#还有命名空间的概念,感觉有点不适用,虽然写代码时可以无视它。。但类文件里面多个方法块花括号还是不适应;同时访问修饰符也多了internal(也可用反射调用该修饰的变量或方法,和java类似)

7.struct类型定义的变量是值类型,class定义的变量是引用类型。因此struct类型定义的对象是分配在栈上面的,而class定义的对象是分配在堆上的;struct可以实现接口

8.C#个人觉得缺点,支持的方法太多,写法上比较随意,和java相比显得有点乱。。。

9.using int32 = System.Int32; 然后在文件中使用int32时,它就会被当作System.Int32处理。这种做法不会创建一个新的数据类型,它只是简化了你的代码编写。在使用using指令时,你不能为内置数据类型创建别名,只能为自定义类型创建别名

1.整体文件夹布局风格统一

还是围绕java项目结构风格,对各个业务代码所在位置分工明确;变量名用开头小写驼峰,类名大写;好处:写多了不会忘记java写法。。。写法上也更舒服

2.组件需要自定义开发

(新增用户控件->画笔Paint自己画->工具箱可自动加载该组件->大组件套小组件随便用)

3.组件-电池组件实现

namespace BatteryMoniterCenter.components
{
    public partial class BatteryFrame : Panel
    {
        Rectangle rect;//绘制区域

        public BatteryFrame()
        {
            InitializeComponent();
            //设置控件样式标志----绘制
            SetStyle(ControlStyles.Selectable, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);//忽略窗口消息,减少闪烁
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);//绘制到缓冲区,减少闪烁
            SetStyle(ControlStyles.UserPaint, true);//控件由其自身而不是操作系统绘制
            SetStyle(ControlStyles.ResizeRedraw, true);//控件调整其大小时重绘
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);//支持透明背景
            rect = this.ClientRectangle;
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            rect = this.ClientRectangle;
            this.Region = new Region(rect);
            rect.Width -= 1;
            rect.Height -= 1;
        }

        //属性扩展:背景色1、背景色2、边框粗细、边框颜色、圆角半径、渐变模式
        private Color bgColor = Color.Gray;
        /// <summary>
        /// 背景色(渐变色中,颜色1)
        /// </summary>
        [DefaultValue(typeof(Color), "Gray"), Description("控件背景色")]
        public Color BgColor
        {
            get { return bgColor; }
            set
            {
                bgColor = value;
                Invalidate();
            }
        }


        [DefaultValue(typeof(Color), "Transparent"), Description("控件背景颜色2")]
        private Color bgColor2 = Color.Transparent;
        public Color BgColor2
        {
            get { return bgColor2; }
            set
            {
                bgColor2 = value;
                Invalidate();
            }
        }

        private Color borderColor = Color.Gray;
        [DefaultValue(typeof(Color), "Gray"), Description("控件边框颜色")]
        public Color BorderColor
        {
            get { return borderColor; }
            set
            {
                borderColor = value;
                if (borderWidth > 0)
                    Invalidate();
            }
        }

        private int borderWidth = 0;
        [DefaultValue(typeof(int), "0"), Description("控件边框粗细")]
        public int BorderWidth
        {
            get { return borderWidth; }
            set
            {
                borderWidth = value;
                Invalidate();
            }
        }


        [DefaultValue(typeof(int), "5"), Description("圆角弧度大小")]
        private int radius = 5;
        public int Radius
        {
            get { return radius; }
            set
            {
                radius = value;
                Invalidate();
            }
        }

        [DefaultValue(typeof(LinearGradientMode), "Vertical"), Description("渐变方式")]
        private LinearGradientMode gradientMode = LinearGradientMode.Vertical;
        public LinearGradientMode GradientMode
        {
            get { return gradientMode; }
            set
            {
                gradientMode = value;
                Invalidate();
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            //重绘外观:如果有边框,画边框、背景、内容
            Graphics g = e.Graphics;//绘图对象           
            g.SmoothingMode = SmoothingMode.HighQuality;  //呈现质量--高质量呈现 
            Rectangle rect1;//定义背景矩形
            GraphicsPath path = new GraphicsPath();//边框圆角路径
            GraphicsPath path2 = new GraphicsPath();//背景圆角路径

            if (rect.Width <= 0 && rect.Height <= 0)
            {
                return;//被最小化后,不刷新
            }

            path = PaintClass.GetRoundBattery(rect, radius, BatteryModel.defaultBuild());//圆角矩形路径
            if (borderWidth > 0)//有边框时
            {
                g.FillPath(new SolidBrush(borderColor), path);//填充边框的圆角矩形
                                                              //内部背景区域矩形 
                rect1 = new Rectangle(rect.X + borderWidth, rect.Y + borderWidth, rect.Width - 2 * borderWidth, rect.Height - 2 * borderWidth);
                //生成内部矩形的圆角矩形路径
                path2 = PaintClass.GetRoundBattery(rect1, radius, BatteryModel.defaultBuild());
            }
            else //无边框
            {
                path2 = path;
                rect1 = rect;
            }
            //背景色填充
            if (bgColor2 != Color.Transparent) //渐变填充
            {
                //渐变画刷
                LinearGradientBrush bgBrush = new LinearGradientBrush(rect1, bgColor, bgColor2, gradientMode);
                g.FillPath(bgBrush, path2);//填充背景
            }
            else
            {
                //纯色填充
                Brush b = new SolidBrush(bgColor);
                g.FillPath(b, path2);
            }

        }
    }
}

4.主界面展示

调整色彩搭配上比较耗时,其他的暂时没难度

读写xml和json等,调用第三方库复制个使用案例即可

5.主界面数据联动

plc对接modbusRUT工具类,配合Slave假数据来联动显示(通过虚拟串口转发,COM1转发COM2)

主要学习了

1.新的创建线程的方式 Task.Run(async() => await)..

2.非主线程中刷新控件if (this.IsHandleCreated)
{
    this.Invoke(new Action(() =>
    {
        refreshPlcData();
    }));
}

3.创建主站 master = ModbusSerialMaster.CreateRtu(serialPort.Open()=>IsOpen=>serialPort);

4 读取functionCode:4的方法=>IModbusMaster master.ReadInputRegistersAsync(slave.SlaveId, slave.StartAddress, (Context.deviceList.Count * 10).ToString().GetUshort());需要和slave中设置的functionCode和slaveId一致

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值