簡體   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