Member 13571364
@Кинжал,
Пожалуйста, смотрите ниже, я попытался сделать простое приложение, освещающее эту проблему,
- Файл MainWindow создается экземпляр MainViewModel, который создает экземпляр класса как TCP подключение.
- Имеющаяся в наличии коллекция создается в классе как TCP подключение
- данные добавляются в наблюдаемую коллекцию "_CanMessage" во время тестирования
- однако он никогда не обновляется до связанного Listview
Я не совсем уверен в именах Привязок в xaml, так что может возникнуть проблема..
Пожалуйста, дайте мне знать, если у вас возникнут дополнительные вопросы.
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>
Dirk Bahle
Я пытался скомпилировать ваш проект, но, похоже, не могу найти определение для 2 методов:
- Я не могу найти определение для этого слова. Гексенкодирование метод
- Я не могу найти определение для этого слова. Писать метод, указанный в обработчике событий нажатия кнопки _главный.Клиент.Запись данных);
- Можете ли вы обновить, чтобы включить их?
- Я думаю, вы используете MVVMLight, верно?
Member 13571364
Мои извинения, я не знал, что вы собираетесь скомпилировать программу.
- Я обновил классы, и теперь он компилируется
- Я очень новичок в c# MVVM, так что не слишком уверен, что это за легкая версия? придется об этом почитать.
Dirk Bahle
Я могу скомпилировать ваш код сейчас но я получаю 2 сообщения об ошибках в выходных данных TW VS:
Система.Окна.Ошибка данных: 40 : BindingExpression path error: 'Message' свойство не найдено на 'object' "MainWindow' (Name=")'. BindingExpression:Path=Message; DataItem='MainWindow' (Name="); целевой элемент - 'ListView' (Name="); целевое свойство - 'ItemsSource' (тип 'IEnumerable')
Система.Окна.Данные ошибка: 40 : BindingExpression путь ошибка: 'Сообщение' имущество не нашел на 'объект' "MainViewModel' (хэш-код=24112512)'. BindingExpression:путь=сообщение; элемента данных='MainViewModel' (хэш-код=24112512); целевой элемент-это элемент управления ListView' (имя="); целевое свойство ', что ItemsSource' (тип 'интерфейс IEnumerable')
Эти сообщения указывают на то, что ваш код хочет привязаться к свойству Message (см. код XAML), но класс MainViewModel не содержит свойства Message.
Класс MainViewModel содержит только класс сообщений. Но этот класс не может рассматриваться для привязки - здесь релевантны только свойства экземпляра объекта.
Я думаю, вам нужно изменить выражение привязки на:
ItemsSource = "{Привязка Клиента}"
2-я проблема, которую я нашел, находится в корне MainWindow.xaml - вам нужно удалить оператор привязки: DataContext="{Binding RelativeSource={RelativeSource Self}}", так как это говорит MainWindow искать в своем экземпляре on object упомянутые свойства.
Это, вероятно, исправление, чтобы сделать изменения видимыми в пользовательском интерфейсе. Если у вас есть дополнительные проблемы, было бы проще, если бы вы сделали перерыв в этом и завершили учебник по WPF... возможно, фиксация примера кода в Репро GitHub также облегчит поиск и исправление дальнейших проблем ...