Reputation: 149
I want to receive a serial string and display in a textbox, I posted a question yesterday about using the background worker, I got lots of help thanks, but still couldn't solve it. So I started a new simplest project that I could: Form 1 has a textbox to display return value, 1 button to connect com port, 1 button to send serial out. When device on com port receives the ? sent, it returns a string which I want to display in the textbox tbEncoderValue. Serial coms handled by SerialPortClass. In SetText is where the error occurs. What is the best & simplest way of writing to this textbox please?
Form1: EDIT Minimised verion posted
namespace TestSensor
{
public partial class Form1 : Form
{
public static TextBox tbE = new TextBox();
// create a SerialPortClass object variable and called it sp
SerialPortClass sp = new SerialPortClass();
public Form1()
{
InitializeComponent();
tbEncoderValue.Text = "0000";
}
private void Form1_Load(object sender, EventArgs e)
{
tbE = tbEncoderValue;
}
}
}
SerialPortClass:
namespace TestSensor
{
public class SerialPortClass : Form
{
internal delegate void SerialDataReceivedEventHandlerDelegate(
object sender, SerialDataReceivedEventArgs e);
string InputData = String.Empty;
public SerialPortClass()
{
serialPort1.DataReceived +=
new System.IO.Ports.SerialDataReceivedEventHandler(port_DataReceived_1);
}
private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
Console.WriteLine("Data recieved");
InputData = serialPort1.ReadExisting();
if (InputData != String.Empty)
{
SetText(InputData);
}
}
public void SetText(string text)
{
Console.WriteLine("set text");
Console.WriteLine(text);
Form1.tbE.Text = text; //causes cross thread operation error here
}
}
}
Form1.tbE.Text = text; //causes cross thread operation error here
After reading @Pavieł Kraskoŭski comment again, I've now got when serial received to InvokeMethod and display a fixed string, but would you pass string variable in please?
public delegate void InvokeDelegate();
public void SetText(string text)
{
Console.WriteLine("set text");
Console.WriteLine(text);
Form1 fm = new Form1();
Form1.tbE.BeginInvoke(new InvokeDelegate(InvokeMethod));
}
public void InvokeMethod()
{
Form1.tbE.Text = "Executed delegate";
}
Upvotes: 2
Views: 666
Reputation: 2053
You can use the method invoker delegate and set the text in your setText method.
this.Invoke((MethodInvoker)delegate{ tbE.Text = textToDisplay; });
or from your code:
public void SetText(string text)
{
Form1 fm = new Form1();
Console.WriteLine("set text");
Console.WriteLine(text);
textToDisplay = text;
fm.Invoke((MethodInvoker)delegate{ tbE.Text = textToDisplay; });
}
Upvotes: 1
Reputation: 149
With thanks to @Paviel I know have: which works, but I don't think using a class variable is the best way of passing string into the InvokeMethod, any comments please?
public delegate void InvokeDelegate();
private string textToDisplay;
public void SetText(string text)
{
Form1 fm = new Form1();
Console.WriteLine("set text");
Console.WriteLine(text);
textToDisplay = text;
Form1.tbE.BeginInvoke(new InvokeDelegate(InvokeMethod));
}
public void InvokeMethod()
{
Form1.tbE.Text = textToDisplay;
}
Upvotes: 0