繁体   English   中英

C#ListView添加项目

[英]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方法不接受参数的随机序列。 它只能接受此处提到的类型的参数:

http://msdn.microsoft.com/zh-CN/library/system.windows.forms.listview.listviewitemcollection.add.aspx

除了logicnp所说的以外,我的猜测是您正在单独的线程上运行while循环(因为否则它将阻塞UI线程)。

解决了最初的问题后,您将需要跨线程边界正确更新UI元素。

这是一个说明问题和解决方案的教程

这实际上只是到目前为止您所提供建议的综合。

到目前为止,给出的要点是:

  1. 将您的数据转换为ListView可以理解的格式。
  2. 分开考虑可以简化测试和维护。
  3. 了解并使用WinForms线程模型。

代码如下:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM