[英]C# listview add items
问候,
我有一种捕获数据包的方法。 捕获后,我想将每个数据包实时添加为列表视图中的一行,因此,一旦捕获数据包,我便要将其添加到列表视图中。
我使用items.Add()时会出现重载参数错误的问题。 请指教!!
这是我的代码:
私人void packetCapturingThreadMethod(){
Packet packet = null;
int countOfPacketCaptures = 0;
while ((packet = device.GetNextPacket()) != null)
{
packet = device.GetNextPacket();
if (packet is TCPPacket)
{
TCPPacket tcp = (TCPPacket)packet;
myPacket tempPacket = new myPacket();
tempPacket.packetType = "TCP";
tempPacket.sourceAddress = Convert.ToString(tcp.SourceAddress);
tempPacket.destinationAddress = Convert.ToString(tcp.DestinationAddress);
tempPacket.sourcePort = Convert.ToString(tcp.SourcePort);
tempPacket.destinationPort = Convert.ToString(tcp.DestinationPort);
tempPacket.packetMessage = Convert.ToString(tcp.Data);
packetsList.Add(tempPacket);
string[] row = { packetsList[countOfPacketCaptures].packetType, packetsList[countOfPacketCaptures].sourceAddress, packetsList[countOfPacketCaptures].destinationAddress, packetsList[countOfPacketCaptures].sourcePort, packetsList[countOfPacketCaptures].destinationPort, packetsList[countOfPacketCaptures].packetMessage };
try {
listView1.Items.Add(packetsList[countOfPacketCaptures].packetType, packetsList[countOfPacketCaptures].sourceAddress, packetsList[countOfPacketCaptures].destinationAddress, packetsList[countOfPacketCaptures].sourcePort, packetsList[countOfPacketCaptures].destinationPort, packetsList[countOfPacketCaptures].packetMessage)
; countOfPacketCaptures++;
lblCapturesLabels.Text = Convert.ToString(countOfPacketCaptures);}
catch (Exception e) { }
}
else if (packet is UDPPacket)
{
UDPPacket udp = (UDPPacket)packet;
myPacket tempPacket = new myPacket();
tempPacket.packetType = "UDP";
tempPacket.sourceAddress = Convert.ToString(udp.SourceAddress);
tempPacket.destinationAddress = Convert.ToString(udp.DestinationAddress);
tempPacket.sourcePort = Convert.ToString(udp.SourcePort);
tempPacket.destinationPort = Convert.ToString(udp.DestinationPort);
tempPacket.packetMessage = Convert.ToString(udp.Data);
packetsList.Add(tempPacket);
string[] row = { packetsList[countOfPacketCaptures].packetType, packetsList[countOfPacketCaptures].sourceAddress, packetsList[countOfPacketCaptures].destinationAddress, packetsList[countOfPacketCaptures].sourcePort, packetsList[countOfPacketCaptures].destinationPort, packetsList[countOfPacketCaptures].packetMessage };
try { dgwPacketInfo.Rows.Add(row);
countOfPacketCaptures++;
lblCapturesLabels.Text = Convert.ToString(countOfPacketCaptures);
}
catch (Exception e) { }
}
}
}
这是因为Add方法不接受参数的随机序列。 它只能接受此处提到的类型的参数:
除了logicnp所说的以外,我的猜测是您正在单独的线程上运行while循环(因为否则它将阻塞UI线程)。
解决了最初的问题后,您将需要跨线程边界正确更新UI元素。
这是一个说明问题和解决方案的教程 。
这实际上只是到目前为止您所提供建议的综合。
到目前为止,给出的要点是:
代码如下:
public partial class Form1 : Form
{
private readonly Device _device;
private readonly PacketBinder _packetBinder;
public Form1()
{
InitializeComponent();
_device = Device.GetInstance();
_packetBinder = PacketBinder.GetInstance(listView1);
var thread = new Thread(WritePackets);
thread.IsBackground = true;
thread.Start();
}
private void WritePackets()
{
Packet packet = null;
int countOfPacketCaptures = 0;
while ((packet = _device.GetNextPacket()) != null)
{
packet = _device.GetNextPacket();
MyPacket tempPacket = null;
if (packet is TCPPacket)
{
TCPPacket tcp = (TCPPacket)packet;
tempPacket = MyPacket.GetInstance();
tempPacket.PacketType = "TCP";
tempPacket.SourceAddress = Convert.ToString(tcp.SourceAddress);
tempPacket.DestinationAddress =
Convert.ToString(tcp.DestinationAddress);
tempPacket.SourcePort = Convert.ToString(tcp.SourcePort);
tempPacket.DestinationPort = Convert.ToString(tcp.DestinationPort);
tempPacket.PacketMessage = Convert.ToString(tcp.Data);
}
else if (packet is UDPPacket)
{
UDPPacket udp = (UDPPacket)packet;
tempPacket = MyPacket.GetInstance();
tempPacket.PacketType = "UDP";
tempPacket.SourceAddress = Convert.ToString(udp.SourceAddress);
tempPacket.DestinationAddress =
Convert.ToString(udp.DestinationAddress);
tempPacket.SourcePort = Convert.ToString(udp.SourcePort);
tempPacket.DestinationPort = Convert.ToString(udp.DestinationPort);
tempPacket.PacketMessage = Convert.ToString(udp.Data);
}
if (tempPacket != null)
{
_packetBinder.AddPacketToView(tempPacket);
}
}
}
}
internal class Device
{
private Device() { }
internal static Device GetInstance()
{
return new Device();
}
internal Packet GetNextPacket()
{
var random = new Random();
var coin = random.Next(2);
Thread.Sleep(500);
if (coin == 0)
{
return new TCPPacket()
{
Data = GetRandomString(random),
SourceAddress = GetRandomString(random),
SourcePort = random.Next(),
DestinationAddress = GetRandomString(random),
DestinationPort = random.Next()
};
}
else
{
return new UDPPacket()
{
Data = GetRandomString(random),
SourceAddress = GetRandomString(random),
SourcePort = random.Next(),
DestinationAddress = GetRandomString(random),
DestinationPort = random.Next()
};
}
}
private string GetRandomString(Random random)
{
var bytes = new byte[16];
random.NextBytes(bytes);
return Convert.ToBase64String(bytes);
}
}
internal class MyPacket
{
private MyPacket() { }
internal static MyPacket GetInstance()
{
return new MyPacket();
}
internal string PacketType { get; set; }
internal string SourceAddress { get; set; }
internal string DestinationAddress { get; set; }
internal string SourcePort { get; set; }
internal string DestinationPort { get; set; }
internal string PacketMessage { get; set; }
}
internal class ThreadSafeListViewMutator
{
private readonly ListView _target;
private ThreadSafeListViewMutator(ListView target)
{
_target = target;
}
internal static ThreadSafeListViewMutator GetInstance(ListView target)
{
return new ThreadSafeListViewMutator(target);
}
internal void AddListViewItem(ListViewItem listItem)
{
Action action = () => _target.Items.Add(listItem);
Delegate asDelegate = action;
var handle = _target.BeginInvoke(asDelegate);
_target.EndInvoke(handle);
}
}
internal class PacketBinder
{
private readonly ThreadSafeListViewMutator _target;
private PacketBinder(ListView target)
{
_target = ThreadSafeListViewMutator.GetInstance(target);
}
internal static PacketBinder GetInstance(ListView target)
{
return new PacketBinder(target);
}
internal void AddPacketToView(MyPacket tempPacket)
{
var listItem = new ListViewItem() { Text = tempPacket.PacketType };
AddSubItem(listItem, "From", tempPacket.SourceAddress + ":"
+ tempPacket.SourcePort);
AddSubItem(listItem, "To", tempPacket.DestinationAddress + ":"
+ tempPacket.DestinationPort);
AddSubItem(listItem, "Message", tempPacket.PacketMessage);
_target.AddListViewItem(listItem);
}
private void AddSubItem(ListViewItem listItem, string attribute, string value)
{
listItem.Text = listItem.Text + @"
" + attribute + " = " + value;
}
}
internal class Packet { }
// Are these really duplicated this way? Seems crazy...
internal class TCPPacket : Packet
{
internal string SourceAddress { get; set; }
internal string DestinationAddress { get; set; }
internal int SourcePort { get; set; }
internal int DestinationPort { get; set; }
internal string Data { get; set; }
}
internal class UDPPacket : Packet
{
internal string SourceAddress { get; set; }
internal string DestinationAddress { get; set; }
internal int SourcePort { get; set; }
internal int DestinationPort { get; set; }
internal string Data { get; set; }
}
同样,一旦它开始工作,就可以重构以创建一个从listview继承的类,并添加自己的重载Add方法,该方法获取任何类的成熟对象并将它们适当地添加到listview中-这样可以节省一些代码重复并您的代码更加简洁,可读性和可维护性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.