Update multiple textboxes at once

  • Thread starter Thread starter Joe Thompson
  • Start date Start date
J

Joe Thompson

Hi,

I have a C# windows form application (.NET 2.0) that reads data over the
serial port and displays the data via textboxes. I get a message 50
times/second. I know I can't update the screen that fast but I would like to
update the data maybe twice a second. Currently, I have about 20 textboxes
that get updated at once. This seems to be a pretty slow process.

I'm looking for suggestions. What is the best way to update the .text
fields of the textboxes so that it happens as fast as possible? Are there
better components to use (such as labels)? Any other alternatives?

Thank you,
Joe
 
I would try and experiment with...databinding...and updating the model,and
let dotnet do the work.


http://www.akadia.com/services/dotnet_databinding.html


you need to create the "model" (which is the datastore of information).

You do the binding of (ex) a textbox, to a property of the "model".

See the article above....and experiment with it.

You could have 2 datastores. The "up to the instance one", and a copy...and
the copy gets its data from the "up to the instance" one...via a
Thread.Timer or something...and you code that to fire every 1/2 second or
something.


I would NOT use a drag and drop timer. I would "code on up" like this
example:
http://msdn2.microsoft.com/en-us/library/system.threading.timer.aspx

and then let the event that fires...do a copy from the "up to the instant"
datastore to the "good enough...every 1/2 second datastore".

Then you can tweak the 1/2 second to something smaller until you find a good
middle ground.
 
Hi,

You should do the serial port processing in a background thread. That is the
first thing to do.
You did not especified if each time you get a message you get a set of
values (for the 20 textboxes). I will assume you do.

In this case what you can do is create a set of values (using a class to
encapsulate them will be the best) when you want to update the interface and
then fire an event in the UI thread ( using Control.Invoke ) to display
them.

something like this:

//worker thread
... getvalues
if ( times == 50 )
{
Values v = new values ( ... all the values )
Control.Invoke( ..... v ..... );
times=0;
}
else
times++;
 
[...]
In this case what you can do is create a set of values (using a class to
encapsulate them will be the best) when you want to update the interface
and
then fire an event in the UI thread ( using Control.Invoke ) to display
them.

And pay close attention to the code example Ignacio posted. Pass all of
the new values in a single call to Invoke(), just as he shows in his
post. Calling Invoke() once for each value will perform poorly.

Depending on how you need to display the text, you may find that you get
the best performance just writing your own control. The TextBox control
has a fair amount of overhead, especially since it relies on window
messages to do all of its data management. So nothing happens without
going through the message pump.

If you write your own control, you can set it up so that you can set the
values directly in the control class instance and then force a redraw
(invalidate). Drawing the text is simple: in your custom control,
override OnPaint() and use Graphics.DrawString() to draw each string in
the control where you want it.

As long as you don't need all of the functionality of the TextBox control,
this could be a better solution (note that you'll still need to follow
Ignacio's advice with respect to the cross-thread interaction...it'll just
perform better without the TextBox).

Pete
 
Hi,

Thanks for the reply. It's an interesting article but seems a bit more
complicated than I was hoping for.

Joe
 
Hi Ignacio,

I currently set CheckForIllegalCrossThreadCalls = false for my form.
I have my SerialPort's DataReceived event call a method that does wrap all
the needed bytes into a class representing the data. I have to do this every
time so I can write it to a log file (not mentioned previously).

Then, I check if the message number mod 25 = 0. If it does, I set all 20
textbox text to the values like this:
textbox1.Text = MyClass.xxx.ToString("000.00");
textbox2.Text = MyClass.yyy.ToString("000.00");
etc.

I know it's probably not the best approach but it does work. I was under
the assumption that the SerialPort actually is running in it's own thread.
Is that wrong? Also, I'm not familiar with the control.invoke you mentioned
but I will look into it if you think it will help.

Thanks for your time and help,
Joe
 
Hi Pete,

Writing my own control is an interesting approach but unfortunately I have
never done this. I am going to look into the Control.Invoke (see my reply to
Ignacio) and see if it helps.

Thanks for your help,
Joe
 
I currently set CheckForIllegalCrossThreadCalls = false for my form.

A minor point, but actually, no you don't; it is a static property -
so you have it set to false for *every* control in the AppDomain.

Marc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top