I want to create program, that will color ellipse in any way depending on the received data in "real time". The data is like: x1-1, x2-1 etc.
I have strange problem, I can see while debugging that, color of filling ellipse should change, but it doesn't happen.
Part of my code with receiving data:
private void ReceiveData()
{
SerialPort serialPort = new SerialPort("COM1", 9600);
serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
serialPort.Open();
}
private static void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
if (indata.Contains(" "))
{
testString = indata.Substring(0, 4);
}
Console.Write(indata);
}
I can see received data in console, even after click on button, that starts receiving data. The testString is to extract single x1-1 from indata, that is still growing during receiving data. I know that it doesn't work like it should but it doesn't matter now.
Code of action on button:
private void button1_Click(object sender, RoutedEventArgs e)
{
ReceiveData();
while (true)
{
if (testString == "x1-1") x1.Fill = Brushes.Blue;
else x1.Fill = Brushes.Red;
}
}
x1 is ellipse that I want to make red or blue. I can set the breakpoint in this function and I can see that it should change. I think the problem is, that program is waiting for close port and finish transmission, and then maybe it would change, but I need to have it in "real time". Anyone knows how to do it?
I believe you are going about this the wrong way. Instead of constantly checking the value of teststring you need to just start the comm port listener and let it run in the background - as this will be on it's own thread. Then you need to create a Data Binding to the color. Whenever the comm port listener parses a string, it can automatically update the color.
First, in the CommPort class:
class MyCommPort : INotifyPropertyChanged
{
SerialPort serialPort = null;
public MyCommPort()
{
serialPort = new SerialPort("COM3", 9600);
serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
serialPort.Open();
}
~MyCommPort()
{
serialPort.Close();
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string testString = null;
string indata = sp.ReadLine();
if (indata.Length >= 4)
{
testString = indata.Substring(0, 4);
// Update the value
if (testString == "x1-1") EllipseBrush = Brushes.Blue;
else EllipseBrush = Brushes.Red;
}
Console.Write(testString);
}
// Create a property that will be bound
private SolidColorBrush ellipseBrush = Brushes.Red;
public SolidColorBrush EllipseBrush
{
get { return ellipseBrush; }
set
{
ellipseBrush = value;
OnPropertyChanged("EllipseBrush");
}
}
// Extend the INotifyPropertyChanged interface
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
// Alert anyone bound to this that the value has changed
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Then, set the Ellipse's DataContext to the CommPort class and bind the Ellipse's Fill property to EllipseBrush.
Now all you have to do is start the Commport listener (ReceiveData();) and the color updates should happen automatically.
For example: MainWindow.xaml
<Window x:Class="delete_me.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Ellipse x:Name="ellipse" Fill="{Binding Path=EllipseBrush}" />
</Grid>
</Window>
And the code behind: MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ellipse.DataContext = new MyCommPort();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With