问题描述
用C#的listbox控件,显示串口收到的数据,收到一个包就显示为一行,包的大小不超过10个字节。串口接收放在0.1秒定时器里,读到完整的包后,就送到listbox里去显示。(现在下位机1秒发一次)现在现象是:串口每收到一个包显示时,listbox里已有的数据就会闪一次。如果在界面上用按键测试,每按一次按键就在listbox里添加一行数据,这样操作不会导致listbox闪烁。各位帮忙分析分析,这是什么原因呀?
解决方案
解决方案二:
你是每次添加一行呢,还是从头到尾添加一遍呢
解决方案三:
引用1楼bdmh的回复:
你是每次添加一行呢,还是从头到尾添加一遍呢
--------------------------------------------------------------------------------------------每次得到一个包后,使用listBox1.Items.Add(newStr);只增加新的一行。
解决方案四:
自己顶下。少于6个字符。
解决方案五:
那把你代码贴上来看看,是不是哪边有刷新什么的
解决方案六:
你把定时器的间隔设为1s试试
解决方案七:
建议你用绑定数据源的方式,不每次现在数据后刷新下数据即可。
解决方案八:
listbox有没有beginupdate/endupdate?将add放在中间看看。
解决方案九:
如果频繁中断主线程而重复更新UI,应该使用SuspendLayout和ResumeLayout。
解决方案十:
其实更好的做法,是不要使用20年就基本未升级的winform,应该使用10年历史的wpf。
解决方案十一:
收到主机的数据就选中显示,收到从机的数据就正常显示。-----------------------------------------------------------------------------------------------------usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;usingSystem.IO.Ports;//uartusingSystem.Collections;//ArrayListnamespace串口测试{publicpartialclassForm1:Form{SerialPortUartPort=newSerialPort();publicList<byte>uartRevBuf=newList<byte>(100);ArrayListcolorMapBuf=newArrayList();string[]strBuf={"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};boolUartInBufReading=false;privateColorRowBackColorAlt=Color.FromArgb(200,200,200);//交替色privateColorRowBackColorSel=Color.FromArgb(0,255,0);//选择项目颜色(R,G,B)publicForm1(){InitializeComponent();//listBox重画,不用系统自带listBox1.DrawMode=DrawMode.OwnerDrawFixed;this.listBox1.DrawItem+=newSystem.Windows.Forms.DrawItemEventHandler(this.listBox1_DrawItem);}privatevoidlistBox1_DrawItem(objectsender,DrawItemEventArgse){BrushmyBrush=Brushes.Black;//listBox的index必须与colorMapBuf的Index对应。if((e.State&DrawItemState.Selected)==DrawItemState.Selected){myBrush=newSolidBrush(RowBackColorSel);}elseif(colorMapBuf[e.Index].ToString()=="1"){myBrush=newSolidBrush(RowBackColorAlt);}else{myBrush=newSolidBrush(Color.White);}e.Graphics.FillRectangle(myBrush,e.Bounds);e.DrawFocusRectangle();//焦点框//文本e.Graphics.DrawString(listBox1.Items[e.Index].ToString(),e.Font,Brushes.Black,e.Bounds,StringFormat.GenericDefault);}privatevoidForm1_Load(objectsender,EventArgse){cbBandRate.SelectedIndex=3;cbDataBit.SelectedIndex=0;cbParity.SelectedIndex=0;cbStopBit.SelectedIndex=0;List<string>s12=newList<string>(1);//匹配出COM端口string[]s1=SearchDeviceNameClass.MulGetHardwareInfo(SearchDeviceNameClass.HardwareEnum.Win32_PnPEntity,"Name");string[]s2=SerialPort.GetPortNames();intuartIsNull=0;if(s1!=null){s12.AddRange(s1);}else{if(s2!=null){if(s2.Length!=0){s12.AddRange(s2);}else{uartIsNull=1;}}else//都为空{uartIsNull=1;}}if(uartIsNull==0)//有uart{foreach(stringttins12){cbUartName.Items.Add(tt);}}else{cbUartName.Items.Add("本计算机没有串口!");this.tabPage2.Parent=null;//隐藏串口配置页//this.tabPage2.Parent=this.tabControl1;//显示串口配置页btnOnOff.Enabled=false;}cbUartName.SelectedIndex=0;//默认显示第一个item}privatevoidbutton1_Click(objectsender,EventArgse){if(!UartPort.IsOpen)//当前串口为关闭,准备打开。{try{//设置串口号string[]strbuf=cbUartName.SelectedItem.ToString().Trim().Split('(',')');inti=0;for(i=0;i<strbuf.Length;i++){if(strbuf[i].Contains("COM")||strbuf[i].Contains("com"))break;}UartPort.PortName=strbuf[i];//配置串口参数UartPort.BaudRate=Convert.ToInt32(cbBandRate.SelectedItem);UartPort.DataBits=Convert.ToInt32(cbDataBit.SelectedItem);switch(cbParity.SelectedItem.ToString()){case"无":UartPort.Parity=Parity.None;break;case"奇校验":UartPort.Parity=Parity.Odd;break;case"偶校验":UartPort.Parity=Parity.Even;break;default:MessageBox.Show("Error:参数不正确!","Error");break;}switch(cbStopBit.SelectedItem.ToString()){case"1":UartPort.StopBits=StopBits.One;break;case"2":UartPort.StopBits=StopBits.Two;break;default:MessageBox.Show("Error:参数不正确!","Error");break;}uartRevBuf.Clear();UartPort.Open();UartPort.DiscardInBuffer();//清空串口输入buffer。btnOnOff.Text="关闭串口";cbUartName.Enabled=false;cbBandRate.Enabled=false;cbDataBit.Enabled=false;cbParity.Enabled=false;cbStopBit.Enabled=false;timer1.Enabled=true;//激活定时器}catch(System.Exceptionex){MessageBox.Show("Error:"+ex.Message,"Error");}}else//当前是开,准备关闭。{while(UartInBufReading);timer1.Enabled=false;UartPort.DiscardInBuffer();UartPort.Close();btnOnOff.Text="打开串口";cbUartName.Enabled=true;cbBandRate.Enabled=true;cbDataBit.Enabled=true;cbParity.Enabled=true;cbStopBit.Enabled=true;}}//定时器100ms中断,用于接收uart内容并处理。privatevoidtimer1_Tick(objectsender,EventArgse){UartInBufReading=true;intuartRevLength=UartPort.BytesToRead;if(uartRevLength!=0)//至少接收到一个字节{byte[]uartRevTmpBuf=newbyte[uartRevLength];//创建串口接收临时数组UartPort.Read(uartRevTmpBuf,0,uartRevLength);//读串口接收数据到数组里UartInBufReading=false;uartRevBuf.AddRange(uartRevTmpBuf);ProcessUartRevData();}UartInBufReading=false;}publicvoidProcessUartRevData()//处理完全部合规的包{while(true){intindexAA=uartRevBuf.IndexOf(0xAA);if(indexAA==-1){return;}if(indexAA==0){uartRevBuf.RemoveAt(0);return;}//没找到包的起始,此元素作废。if(uartRevBuf[indexAA-1]!=0xF0&&uartRevBuf[indexAA-1]!=0x0F){uartRevBuf.RemoveAt(indexAA);return;}//移除不合适的数据,(index=0,个数)if(indexAA>1){uartRevBuf.RemoveRange(0,(indexAA-1));}if((uartRevBuf[0]==0xF0||uartRevBuf[0]==0x0F)&&uartRevBuf[1]==0xAA){if(uartRevBuf.Count<4){return;}elseif(uartRevBuf[2]>uartRevBuf.Count-2){return;}else{//intcopyLenght=uartRevBuf[3];intcopyCnt=1;stringstrTmp=string.Empty;bytetmpp=0;do{tmpp=uartRevBuf[copyCnt++];strTmp+=strBuf[tmpp>>4]+strBuf[tmpp&0x0F]+"";}while(copyCnt<uartRevBuf[2]+2);if(uartRevBuf[0]==0xF0){colorMapBuf.Add(1);}//来自主机else{colorMapBuf.Add(0);}//来自从机listBox1.Items.Add(strTmp);//送出字符串uartRevBuf.RemoveRange(0,copyCnt);}}}}privatevoidbutton2_Click(objectsender,EventArgse){listBox1.Items.Clear();colorMapBuf.Clear();}privatevoidcbUartName_MouseClick(objectsender,MouseEventArgse){//点击comboBox的显示区就产生下拉条。cbUartName.DroppedDown=true;}privatevoidbutton4_Click(objectsender,EventArgse){listBox1.Items.Add("第xxxxxxxxxx");colorMapBuf.Add(0);}privatevoidbutton3_Click(objectsender,EventArgse){listBox1.Items.Add("第xxxxxxxxxx");colorMapBuf.Add(1);}}}
解决方案十二:
引用7楼ggw的回复:
listbox有没有beginupdate/endupdate?将add放在中间看看。
这个试过,没有改善。
解决方案十三:
引用6楼liuwei1128的回复:
建议你用绑定数据源的方式,不每次现在数据后刷新下数据即可。
可否详细说一下?