小白学习Winform 遇到的问题总结

## 小白学习Winform 遇到的问题总结*

需求:

公司需要做一个血压体重一体机,功能就是可以配置血压器、体重器、读卡器等参数,实现刷卡自动测量体重血压等数据,这对于一个没有接触过winform的小白而言还是很有难度的

设计思路:

1、创建两个窗体,A和B,A窗体负责配置仪器信息,B窗体负责测量数据进行展示
2、创建了四个类 :
(1)ReadCardInfo(负责读取患者信息,页面展示);
(2)WeightMachine(连接体重仪,读取串口数据);
(3)BloodPressure(连接血压器,读取高低压、心率数据)
(4)ScanerCode(扫码盒子,患者可以通过二维码直接进行扫码测量)
3、创建两个线程ReadThread、MeasureThread 分别进行读卡和测量操作

遇到的问题总结以及解决方法:

1、最大化窗口并且去除边框

//设置窗体位于左上角
this.StartPosition = 0;
//去除窗体边框
this.FormBorderStyle = FormBorderStyle.None;
//窗体最大化
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;  

2、取消跨线程检查,否则在给控件赋值的时候会报错

//取消跨线程检查
Control.CheckForIllegalCrossThreadCalls = false;

3、窗体加载和label控件赋值的时候会闪烁,可能是由于窗体添加背景图片引起的

//减少闪烁
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);//双通道渲染
this.UpdateStyles();

总结分享:

第一次做winform项目,比较差劲,但是还是有很多收获的;接下来分享代码给大家,希望大家能够对大家有帮助
(1)读卡类ReadCardInfo

#region  描述
/
///作者:XXXX
///时间:XXX
///描述:读卡操作
/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AppWithoutBlutdruckAndWeight
{
    public class ReadCardInfo
    {
        //读卡器类型,1是明华,2德卡D3  默认是德卡
        public string ReadCardType = "2";
        //寻卡
        [DllImport("lib\\dcrf32.dll", EntryPoint = "dc_card")]
        public static extern Int16 dc_card(Int16 icdev, int mode, ref long Snr);
        //打开设备
        [DllImport("lib\\dcrf32.dll", EntryPoint = "dc_init")]
        public static extern Int16 dc_init(int port, int baud);
        //读取数据     从卡中读数据
        [DllImport("lib\\dcrf32.dll")]
        public static extern Int16 dc_read(Int16 icdev, int adr, [MarshalAs(UnmanagedType.LPArray)] byte[] sdata);
        //断开设备
        [DllImport("lib\\mwrf32.dll", EntryPoint = "rf_exit")]
        public static extern Int16 rf_exit(Int16 icdev);
        //读取数据     
        [DllImport("lib\\mwrf32.dll")]
        public static extern Int16 rf_read(Int16 icdev, int adr, [MarshalAs(UnmanagedType.LPArray)] byte[] sdata);

        [DllImport("lib\\dcrf32.dll", EntryPoint = "dc_load_key_hex")]
        public static extern Int16 dc_load_key_hex(Int16 icdev, int mode, int secnr, string keybuff);

        //验证某一扇区密码     
        [DllImport("lib\\dcrf32.dll")]
        public static extern Int16 dc_authentication(Int16 icdev, int _Mode, int _SecNr);
        //中止对该卡操作
        [DllImport("lib\\dcrf32.dll", EntryPoint = "dc_halt")]
        public static extern Int16 dc_halt(Int16 icdev);
        //断开设备
        [DllImport("lib\\dcrf32.dll", EntryPoint = "dc_exit")]
        public static extern Int16 dc_exit(Int16 icdev);
        //连接设备
        [DllImport("lib\\mwrf32.dll", EntryPoint = "rf_init")]
        public static extern Int16 rf_init(int port, int baud);
        //寻卡
        [DllImport("lib\\mwrf32.dll", EntryPoint = "rf_card")]
        public static extern Int16 rf_card(Int16 icdev, int mode, ref long Snr);
        //中止对该卡操作
        [DllImport("lib\\mwrf32.dll", EntryPoint = "rf_halt")]
        public static extern Int16 rf_halt(Int16 icdev);
        //蜂鸣器
        [DllImport("lib\\dcrf32.dll", EntryPoint = "dc_beep")]
        public static extern Int16 dc_beep(Int16 icdev, int version);
        //蜂鸣器
        [DllImport("lib\\mwrf32.dll", EntryPoint = "rf_beep")]
        public static extern Int16 rf_beep(Int16 icdev, int version);

        public string readCard()
        {
            string cardNo = "";
            //寻卡     成功/失败
            Int16 icdev = OpenCard();
            if (icdev < 0) return string.Empty;
            //验证     
            bool success = VerifyPassword(icdev, 1, 0);
            if (!success) return string.Empty;
            //读卡
            cardNo = ReadCard(icdev, 1, 0).Replace("\0", "").Trim();
            return cardNo;
        }

        public Int16 OpenCard()
        {
            if (!string.IsNullOrEmpty(ReadCardType) && ReadCardType == "2")
            {
                Int16 icdev = dc_init(100, 9600);
                if (icdev < 0)
                {
                    return icdev;
                }
                long cardNo = 0;
                int result = dc_card((Int16)icdev, 1, ref cardNo);
                if (result == 0)
                {
                    return icdev;
                }
                else
                {
                    // 寻卡失败
                    dc_halt((Int16)icdev);
                    dc_exit(icdev); //关闭设备
                    return -1;
                }
            }
            else
            {
                // 打开设备
                Int16 icdev = rf_init(0, 9600);
                if (icdev < 0)
                {
                    return icdev;
                }
                // 寻卡
                long icCardNo = 0;
                int result = rf_card((Int16)icdev, 1, ref icCardNo);
                if (result == 0)
                {
                    // 寻卡成功 卡号为icCardNo
                    return icdev;
                }
                else
                {
                    // 寻卡失败
                    rf_halt((Int16)icdev);
                    rf_exit(icdev); //关闭设备
                    return -1;
                }
            }
            
        }

        private bool VerifyPassword(Int16 icdev, int sector, int block)
        {
            int ints = dc_load_key_hex(icdev, 0, sector, "FFFFFFFFFFFF");
            if (ints != 0) return false;
            // 验证密码
            int result = dc_authentication(icdev, 0, sector);
            if (result != 0)
            {
                dc_halt((Int16)icdev);
                dc_exit(icdev);  //关闭设备
                return false;
            }
            return true;
        }

        private string ReadCard(Int16 icdev, int sector, int block)
        {      
            int address = sector * 4 + block;
            byte[] temp1 = new byte[64 * 8];
            //德卡
            if (!string.IsNullOrEmpty(ReadCardType) && ReadCardType == "2")
            {
                int result = dc_read(icdev, address, temp1);
                if (result == 0)
                {
                    dc_beep(icdev, 5);//提示音
                    return Encoding.Default.GetString(temp1);
                }
                else
                {
                    dc_beep(icdev, 20);//提示音
                    return "";
                }
            }
            else//明华
            {
                int result = rf_read(icdev, address, temp1);
                if (result == 0)
                {
                    rf_beep(icdev, 5);//提示音
                    return Encoding.Default.GetString(temp1);
                }
                else
                {
                    rf_beep(icdev, 20);//提示音
                    return "";
                }
            }
        }
    }
}

(2)体重测量 WeightMachine

#region  描述
/
///作者:XXXX
///时间:XXXX
///描述:连接串口读取体重数据
/
#endregion

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AppWithoutBlutdruckAndWeight
{
    public class WeightMachine
    {
        /// <summary>
        /// 串口对象
        /// </summary>
        private SerialPort serialPort = new SerialPort();
        /// <summary>
        /// 体重数据
        /// </summary>
        private string result = "0";
        /// <summary>
        /// 体重器类型
        /// </summary>
        public string WeightType = string.Empty;
        /// <summary>
        /// 计时器,一分钟未读出数据,停止读取
        /// </summary>
        public int CountTime = 0;


        public string ReadMessage(string baudrate,string Name)
        {
            try
            {
                WeightType = Name;
                if (!serialPort.IsOpen)
                {
                    string[] portName = SerialPort.GetPortNames();
                    serialPort.PortName = portName[0]; //端口名称
                    serialPort.BaudRate = Convert.ToInt32(baudrate);   // 波特率4800
                    serialPort.DataBits = 8;      // 每个字节的标准数据位长度。
                    serialPort.StopBits = StopBits.One; //停止一位
                    serialPort.Parity = Parity.None;    //偶校验
                    //serialPort.ReadTimeout = 500; //接收延时ms
                    //serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                    serialPort.Open();
                }
                if (serialPort.IsOpen)
                {
                    CountTime = 0;
                    while (true)
                    {
                        Thread.Sleep(1000);
                        CountTime++;
                        byte[] readData = new byte[2048];     //获取接收缓冲区中数据的字节数。
                        serialPort.Read(readData, 0, readData.Length);//从SerialPort 输入缓冲区中读取。
                        string temp = Encoding.Default.GetString(readData);
                        result = ParsingDataByType(temp.Trim());
                        if (!string.IsNullOrEmpty(result) && result != "0")
                        {
                            break;
                        }
                        if (CountTime > 120)
                        {
                            result = "-1";
                            break;
                        }
                        serialPort.DiscardInBuffer();
                        serialPort.DiscardOutBuffer();
                    }
                    serialPort.Close();
                }
                return result;
            }
            catch (Exception ex)
            {
                //MessageBox.Show("“" + ex.Message + "”设置硬件功能不可用!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return "";
            }
        }
       
        public void CloseWeight() => serialPort.Close();


        #region 解析体重数据
        /// <summary>
        /// 解析数据
        /// </summary>
        private string ParsingDataByType(string data)
        {
            string weightresult = "";
            switch (WeightType)
            {
                case "上海志荣轮椅体重秤":
                    string[] weight = data.Trim('=').Split('=');
                    if (weight.Length > 3 && (weight[0].Trim() == weight[1].Trim() && weight[1].Trim() == weight[2].Trim()))
                    {
                        char[] c = weight[0].Trim().ToCharArray();
                        Array.Reverse(c);
                        weightresult = Convert.ToInt32(new string(c)).ToString();
                    }
                    break;
                case "电子多功能秤seca685":
                    break;
            }
            return weightresult;
        }
        #endregion
    }
}

3、读取血压 BloodPressure

#region  描述
/
///作者:XXXX
///时间:XXXX
///描述:连接串口读取血压、心率
/
#endregion
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;

namespace AppWithoutBlutdruckAndWeight
{
    public class BloodPressure
    {
        /// <summary>
        /// 血压器类型
        /// </summary>
        public string BloodPreType = string.Empty;
        SerialPort comm = new SerialPort();

        public BloodPressure()
        {

        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <returns></returns>
        public string ReadMessage(string baudrate,string Name)
        {
            BloodPreType = Name;
            try
            {
                string result = string.Empty;
                string[] portName = SerialPort.GetPortNames();
                comm.PortName = portName[0]; //端口名称
                comm.BaudRate = Convert.ToInt32(baudrate);
                comm.Parity = System.IO.Ports.Parity.None;
                comm.DataBits = 8;
                comm.StopBits = System.IO.Ports.StopBits.One;                
                comm.Handshake = System.IO.Ports.Handshake.None;
                comm.ReadTimeout = 90000;
                Thread.Sleep(1000);
                //接收缓冲区大小
                comm.Open();
                //读取并解析数据
                return ParsingDataByType();               
            }
            catch (Exception ex)
            {
                return "-1";
            }
            finally
            {
                comm.Close();
            }
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        public void CloseBlood() => comm.Close();

        #region 解析血压、心率数据
        /// <summary>
        /// 解析数据
        /// </summary>
        private string ParsingDataByType()
        {
            string bloodResult = "";
            string result = "";
            switch (BloodPreType)
            {
                case "健太郎血压仪9020(RVIII)":
                    
                    break;
                case "RBP-9000c和RBP-9001台式血压计":
                    int count = 0;
                    string subStr = "";
                    while (true)
                    {
                        byte[] buf = new byte[1];
                        comm.Read(buf, 0, 1);
                        string str = Convert.ToString(buf[0], 10);
                        result += str;
                        //前24位信息组成 前导码、设备版本、数据长度、类型标识、类型子码、用户标识、测量时间
                        if (result.Length > 24)
                        {                           
                            subStr += str;
                            if (subStr.Length >= 3)
                            {
                                subStr = subStr.TrimStart('0');
                                bloodResult += subStr + "|";
                                count++;
                                subStr = "";
                            }
                            if (count >= 3) break;                          
                        }                       
                    }
                    bloodResult = bloodResult.Trim('|');
                    break;
            }
            return bloodResult;
        }
        #endregion
    }
}

(4)扫码盒子的代码我就不贴了,网上自行搜索,或者留言给我

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1. 学习C#语言基础:Winform框架是基于C#语言开发的,因此学习C#语言是学习Winform框架的前提。 2. 熟悉Winform框架的基本概念和组件:了解Winform框架的基本概念和组件,如窗体、控件、事件等,对于开发Winform应用是至关重要的。 3. 学习Winform框架的常用控件:Winform框架提供了丰富的控件,如文本框、按钮、标签等,学习这些控件的使用方法和属性设置,可以帮助开发者快速开发Winform应用。 4. 掌握Winform框架的布局方式:Winform框架提供了多种布局方式,如绝对布局、流式布局、表格布局等,掌握这些布局方式可以使应用的界面更加美观和易于布局。 5. 学习Winform框架的事件处理:Winform框架的事件处理是应用开发中的重要部分,通过学习事件处理的方法和技巧,可以使应用的交互更加灵活和友好。 6. 熟悉Winform框架的数据绑定:Winform框架提供了数据绑定功能,可以将数据与应用界面进行绑定,学习数据绑定的使用方法可以提高应用的开发效率和数据展示的效果。 7. 学习Winform框架的高级功能:Winform框架还提供了许多高级功能,如多线程、网络通信、打印等,学习这些高级功能可以为应用的开发提供更多的选择和解决方案。 8. 实践:学习Winform框架的最好方法是通过实践来掌握,可以选择一些简单的应用进行开发和练习,逐步提高自己的应用开发技能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值