[英]Logic issue on reading ALL data from the from the listbox that is coming from thread in c#
我正在修改第一个问题尝试。
我需要帮助将列表框中的数据传递给另一个方法,因此,每次列表框获取数据时,都需要从胎面将其添加到数据中,它还应该将该数据发送到我的新方法以及我的列表中,因为在这种方法中,我会正在做一些解析,因为列表框中的数据是长字符串条形码,但我不需要解析数据的帮助,因为我可以做到这一点,我需要帮助的部分只是将数据从传递给它的线程传递给列表框,它也应该发送到我的方法ReadAllData(),因此在该方法中,我将接收到数据,然后进行解析以进行返回。
这是存储列表框并从telnet端口23的线程接收数据的方法
这是我需要将lst_BarcodeScan中的数据发送到方法ReadAllData方法并将其存储到我的列表中的代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.Remoting.Messaging;
using System.Security.Authentication.ExtendedProtection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BarcodeReceivingApp
{
public class TelnetConnection
{
private Thread _readWriteThread;
private TcpClient _client;
private NetworkStream _networkStream;
private string _hostname;
private int _port;
private BarcodeReceivingForm _form;
private bool _isExiting = false;
public TelnetConnection(string hostname, int port)
{
this._hostname = hostname;
this._port = port;
}
public TelnetConnection()
{
}
public void ServerSocket(string ip, int port, BarcodeReceivingForm f)
{
this._form = f;
try
{
_client = new TcpClient(ip, port);
}
catch (SocketException)
{
MessageBox.Show(@"Failed to connect to server");
return;
}
_networkStream = _client.GetStream();
_readWriteThread = new Thread(ReadWrite);
//_readWriteThread = new Thread(() => ReadWrite(f));
_readWriteThread.Start();
}
public void Exit()
{
_isExiting = true;
}
public void ReadWrite()
{
var received = "";
do
{
received = Read();
if (received == null)
break;
if (_form.lst_BarcodeScan.InvokeRequired)
{
_form.lst_BarcodeScan.Invoke(new MethodInvoker(delegate
{
_form.lst_BarcodeScan.Items.Add(received + Environment.NewLine);
}));
}
} while (!_isExiting);
CloseConnection();
}
public List<string> ReadAllData()
{
var obtainData = new List<string>();
return obtainData;
}
public string Read()
{
var data = new byte[1024];
var received = "";
var size = _networkStream.Read(data, 0, data.Length);
if (size == 0)
return null;
received = Encoding.ASCII.GetString(data, 0, size);
return received;
}
public void CloseConnection()
{
MessageBox.Show(@"Closed Connection",@"Important Message");
_networkStream.Close();
_client.Close();
}
}
}
主类,它将从telnetconnection类或我将添加的任何其他类中调用方法。
using System;
using System.Windows.Forms;
namespace BarcodeReceivingApp
{
public partial class BarcodeReceivingForm : Form
{
//GLOBAL VARIABLES
private const string Hostname = "myip";
private const int Port = 23;
private TelnetConnection _connection;
public BarcodeReceivingForm()
{
InitializeComponent();
//FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
}
private void btn_ConnectT_Click(object sender, EventArgs e)
{
_connection = new TelnetConnection(Hostname, Port);
_connection.ServerSocket(Hostname, Port, this);
}
private void btn_StopConnection_Click(object sender, EventArgs e)
{
//_connection = new TelnetConnection(Hostname, Port);
//_connection.ServerSocket(Hostname, Port, this);
_connection.Exit();
}
private void btn_RemoveItemFromListAt_Click(object sender, EventArgs e)
{
for (var i = lst_BarcodeScan.SelectedIndices.Count - 1; i >= 0; i--)
{
lst_BarcodeScan.Items.RemoveAt(lst_BarcodeScan.SelectedIndices[i]);
}
}
private void BarcodeReceivingForm_Load(object sender, EventArgs e)
{
lst_BarcodeScan.SelectionMode = SelectionMode.MultiSimple;
}
private void btn_ApplicationSettings_Click(object sender, EventArgs e)
{
var bcSettingsForm = new BarcodeReceivingSettingsForm();
bcSettingsForm.Show();
}
private void btn_ClearBarcodeList_Click(object sender, EventArgs e)
{
lst_BarcodeScan.Items.Clear();
}
}
}
在不增加线程复杂性的情况下实现的最简单方法是,在将和项添加到listbox
时在listbox
上引发一个事件。 问题是listbox
没有任何允许执行此操作的事件,但是您可以使用十几行代码创建自己的版本。
目标是创建listbox
的派生控件,然后向其中添加一个方法,以在添加项目和宾果游戏时触发自定义事件。
这是带有自定义EventArgs
的自定义listbox
类。
// custom override class over the list box so we can create an event when items are added
public class ListBoxWithEvents : ListBox
{
// the event you need to bind to know when items are added
public event EventHandler<ListBoxItemEventArgs> ItemAdded;
// method to call to add items instead of lst.Items.Add(x);
public void AddItem(object data)
{
// add the item normally to the internal list
var index = Items.Add(data);
// invoke the event to notify the binded handlers
InvokeItemAdded(index);
}
public void InvokeItemAdded(int index)
{
// invoke the event if binded anywhere
ItemAdded?.Invoke(this, new ListBoxItemEventArgs(index));
}
}
// basic event handler that will hold the index of the item added
public class ListBoxItemEventArgs : EventArgs
{
public int Index { get; set; } = -1;
public ListBoxItemEventArgs(int index)
{
Index = index;
}
}
现在,您需要使用ListBoxWithEvents
来更改form
上的listbox
。 您有2种方法可以做到这一点,但我会给您最简单的方法。 编译代码,然后进入form
的设计窗口。 在您的工具箱中,您现在应该拥有ListBoxWithEvents
控件,您可以简单地拖放form
并替换您拥有的form
。 由于它是从listbox
派生的,因此它具有其他功能。 它没有丢失以前的任何东西。
现在您需要更改2件事。 在您的form
选择新的ListBoxWithEvents
控件,然后进入属性事件,您将找到名为ItemAdded
的新事件,您可以双击该事件,它应该创建一个如下所示的事件。 我还抛出了一个示例MessageBox
,它显示了您所需要的全部。
private void ListBox1_ItemAdded(object sender, ListBoxItemEventArgs e)
{
MessageBox.Show("Item was added at index " + e.Index + " and the value is " + listBox1.Items[e.Index].ToString());
}
最后,为了触发该事件,您需要使用新方法lst.AddItem(object);
而不是lst.Items.Add(object);
因此,根据您的示例代码,您需要更改以下内容:
_form.lst_BarcodeScan.Invoke(new MethodInvoker(delegate
{
_form.lst_BarcodeScan.Items.Add(received + Environment.NewLine);
}));
对此:
_form.lst_BarcodeScan.Invoke(new MethodInvoker(delegate
{
_form.lst_BarcodeScan.AddItem(received + Environment.NewLine);
}));
尝试一下,现在每次添加到列表中时,都应该触发该事件。
由于您是编程的新手,因此我发现必须提及此事件将在UI线程而不是您创建的线程上触发,这一点很重要。 这意味着它的行为就像在单击button
触发button_click(object sender, EventArgs e)
事件一样。 无需任何特殊线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.