[英]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.