@Dirk,
Please see below, I have tried to make a simple application highlighting the issue,
- Mainwindow creates an instance of MainViewModel which creates an instance of the TcpConnection class.
- The observable collection is created in the TcpConnection class
- data is added to the observable collection "_CanMessage" during testing
- however its is never updated to the bound Listview
I am not entirely sure about the binding names in the xaml so there could be the issue..
Please let me know if you have any further questions.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Net.Sockets;
using System.Threading;
using System.Windows;
using static SampleProj.MainViewModel;
namespace SampleProj
{
public partial class MainWindow : Window
{
MainViewModel _main;
public MainWindow()
{
InitializeComponent();
_main = new MainViewModel();
DataContext = _main;
}
private void Connect_Button_Click(object sender, RoutedEventArgs e)
{
_main.Client.Connect();
}
private void Start_Button_Click(object sender, RoutedEventArgs e)
{
byte[] data = { 42, 0, 17, 2, 0, 22, 0, 0, 22, 43 };
_main.Client.Write(data);
}
}
class MainViewModel : ObservableObject
{
public TcpConnection Client { get; private set; }
public MainViewModel()
{
Client = new TcpConnection();
}
public class Message
{
public string CANMessage { get; set; }
}
}
public class TcpConnection : ObservableObject
{
TcpClient client;
Thread threadClientReceive;
NetworkStream clientStream;
ObservableCollection<Message> _CanMessage = new ObservableCollection<Message>();
bool receiveThreadAlive = false;
bool flagThreadRunning = false;
bool clientIsConnected = false;
string identifier = string.Empty;
string data = string.Empty;
public TcpConnection()
{
}
public void Connect()
{
client = new TcpClient();
var result = client.BeginConnect("192.168.0.1", 10000, null, null);
var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2));
threadClientReceive = new Thread(new ParameterizedThreadStart(TcpReceive));
flagThreadRunning = true;
receiveThreadAlive = true;
threadClientReceive.Start(client);
if (!success)
{
throw new Exception();
}
if (client.Connected)
{
clientIsConnected = true;
}
}
public void TcpReceive(object client)
{
string bitString = string.Empty;
bool startBitFound = false;
byte startBit = 42;
byte stopBit = 43;
List<byte> receiveDataList = new List<byte>();
TcpClient tcpClient = (TcpClient)client;
if (tcpClient.Connected)
{
clientStream = tcpClient.GetStream();
}
byte[] buffer = new byte[1024];
while (flagThreadRunning)
{
int bytesRead = 0;
try
{
bytesRead = clientStream.Read(buffer, 0, buffer.Length);
}
catch { }
if (bytesRead == 0)
{
break;
}
for (int i = 0; i < buffer.Length; i++)
{
if (buffer[i] == startBit)
{
startBitFound = true;
}
if (startBitFound)
{
receiveDataList.Add(buffer[i]);
}
if (buffer[i] == stopBit)
{
if (receiveDataList.Count == 0)
break;
else
{
string message = HexEncoding.ToString(receiveDataList.ToArray());
if (message.Length > 0)
{
_CanMessage.Add(new Message { CANMessage = message });
}
startBitFound = false;
receiveDataList.Clear();
break;
}
}
}
}
}
public void Write(byte[] data)
{
clientStream = client.GetStream();
try
{
clientStream.Write(data, 0, data.Length);
}
catch
{
}
}
}
public class HexEncoding
{
public HexEncoding()
{
}
public static string ToString(byte[] bytes)
{
string hexString = "";
for (int i = 0; i < bytes.Length; i++)
{
hexString += bytes[i].ToString("X2");
}
return hexString;
}
}
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
<Window x:Class="SampleProj.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SampleProj"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="525">
<Grid Margin = "0,0,-6.6,-242.2" >
< Button Name="conect" Content="Connect" HorizontalAlignment="Left" Margin="119,37,0,0" VerticalAlignment="Top" Width="75" Click="Connect_Button_Click"/>
<Button Name = "start" Content="Start Session" HorizontalAlignment="Left" Margin="240,37,0,0" VerticalAlignment="Top" Width="100" Click="Start_Button_Click"/>
<ListView ItemsSource = "{Binding Message}" Grid.ColumnSpan="5" Grid.Column="2" HorizontalAlignment="Left" Height="489" Margin="29.4,65.6,0,0" Grid.Row="2" Grid.RowSpan="11" VerticalAlignment="Top" Width="429">
<ListView.View>
<GridView>
<GridViewColumn Width = " 200" Header="Message" DisplayMemberBinding="{Binding CANMessage}" ></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>