C#listview添加项目

时间:2010-03-22 02:59:00

标签: c# listview

问候,

我有一种捕获数据包的方法。捕获后我想实时添加每个数据包作为listview中的一行,所以一旦我捕获数据包,我想将它添加到列表视图中。

当我使用items.Add()时我会得到重载参数错误的问题。 请指教!!

这是我的代码:

private 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) { }


                }


            }
        }

4 个答案:

答案 0 :(得分:5)

那是因为Add方法不接受随机的参数序列。它只接受这里提到的类型的参数:

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

答案 1 :(得分:3)

除了logicnp所说的,我的猜测是你在一个单独的线程上运行你的 while 循环(因为否则它会阻止UI线程)。

修复初始问题后,您需要跨线程边界正确更新UI元素。

这是解释问题和解决方案的tutorial

答案 2 :(得分:2)

这实际上只是你迄今为止给出的建议的综合。

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

  1. 将数据转换为ListView可以理解的格式。
  2. 分开关注,使测试和维护更容易。
  3. 了解并使用WinForms线程模型。
  4. 代码如下:

    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; }
    }
    

答案 3 :(得分:1)

此外,一旦你开始工作,重构创建一个继承自listview的类,并添加你自己的重载Add方法,它接受你所有类的完整对象,并将它们适当地添加到listview中 - 这将为你节省一些代码重复并使您的代码更清晰,更易读和可维护。