У меня есть задача, которая запускает операцию непрерывного чтения TCP, когда эта операция чтения читает закодированное в JSON сообщение с удаленного сервера, она отправляет событие в класс Command.cs, где обрабатывает необработанный JSON и преобразует его в класс Response, выполните необходимые проверки и затем инициирует событие «Завершено», когда в конечном итоге клиент подписывается на то, где он может получить класс Response, который можно добавить в наблюдаемую коллекцию.
Я пытался реализовать RaisePropertyChanged, который вызывает функцию Invoke в Dispatcher, которая должна корректно обновлять ObservableCollection.
TCPRequest.cs
private static CancellationTokenSource cancellation;
private static event OnDataReceived datareceivedevent;
public static event OnDataReceived DataReceivedEvent
{
add
{
if(datareceivedevent == null)
{
datareceivedevent += value;
}
}
remove
{
datareceivedevent -= value;
}
}
private static async void ReadOperation(object t)
{
var token = (CancellationToken)t;
var stream = tcpClient.GetStream();
var byteBuffer = new byte[tcpClient.ReceiveBufferSize];
while (!token.IsCancellationRequested)
{
int lRead = 0;
if (stream.DataAvailable)
{
lRead = await stream.ReadAsync(byteBuffer, 0, byteBuffer.Length);
}
if (lRead > 0)
{
var response = ASCIIEncoding.ASCII.GetString(byteBuffer, 0, lRead);
datareceivedevent(response);
}
}
}
public static void StartReading()
{
Task.Factory.StartNew(ReadOperation, cancellation.Token, cancellation.Token);
}
Приведенный выше код является задачей, которая выполняется до тех пор, пока не будет запрошена отмена. Когда данные доступны, они преобразуются в строку и запускают событие (показано выше).
Command.cs
public event OnDataReceivedDeserialized OnDataReceivedDeserialized;
public bool Execute()
{
this.JSONFormat = ToJson();
TCPRequest.DataReceivedEvent += TCPRequest_DataReceivedEvent;
if (!JSONFormat.Equals(string.Empty))
{
return TCPRequest.SendToServer(this);
}
else
{
return false;
}
}
Функция execute находится в классе Command, который обрабатывает все необходимое для отправки JSON на сервер. Этот класс Command подписывается на событие TCPRequest datareceivedevent.
if (TCPRequest.IsConnected)
{
Command cmd = new Command();
cmd.RequestCommand = new Request(RequestType.info);
cmd.OnDataReceivedDeserialized += Cmd_OnDataReceivedDeserialized;
cmd.Execute();
}
public void Cmd_OnDataReceivedDeserialized(RequestResponse response)
{
LoPyList.Add(new LoPy() { name = "Test", id = "00" });
}
А затем над ним будет создана команда, которая подписывается на командное событие, куда пойдет значение ответа сервера.
GraphViewModel.cs
private ObservableCollection<LoPy> lopyList;
public ObservableCollection<LoPy> LoPyList
{
get { return lopyList; }
set {
lopyList = value;
RaisePropertyChangedEvent("LoPyList"); }
}
И, наконец, над списком LoPyList, который привязан к комбинированному списку интерфейса.
GraphView.xaml
<ComboBox Grid.Row="1" ItemsSource="{Binding Path=LoPyList}"
DisplayMemberPath="name"/>
Мне нужно то, что функция внутри ViewModel обновляет LoPyList и я могу просматривать его в пользовательском интерфейсе.