Forum: PC-Programmierung Problem mit listView


von Sven H. (Gast)


Lesenswert?

Hallo, ich habe mit dem listView unter C# ein Problem.
Und zwar verwende ich in meinem Projekt zwei listView.
Diese will ich folgendermaßen so initialisieren:

listView1.View = View.Details;
listView1.Columns[0].Text="Nr.";
listView1.Columns[1].Text="MESSAGE";
listView1.Columns[2].Text="LENGTH";
listView1.Columns[3].Text="DATA";

listView2.View = View.Details;
listView2.Columns[0].Text="Nr.";
listView2.Columns[1].Text="MESSAGE";
listView2.Columns[2].Text="LENGTH";
listView2.Columns[3].Text="DATA";

Beim zweiten listView da mekert das Microsoft Visula Studio .NET 2003
weil ich die Namen schon eimal im listView1 verwendet habe. WIe kann
ich das trotzdem machen?

von Sven H. (Gast)


Angehängte Dateien:

Lesenswert?

Ich möchte mein Programm so gestalten wie auf diesem Bild.

von Locutus (Gast)


Lesenswert?

Hallo Sven.

Also ich nehme mal an du hast bei dem Beispielcode oben schon irgendwo
angegeben, das du 4 Columns in deinen Listviews hast. Ansonsten
bekommst du nämlich einen Fehler, das die Spalten noch nicht
Funktionieren.

Davon mal abgesehen würde ich dein "Problem" so lösen.

listView1.View = View.Details;
listView1.Columns.Add("Nr.",100,HorizontalAlignment.Left);
listView1.Columns.Add("MESSAGE",100,HorizontalAlignment.Left);
listView1.Columns.Add("LENGTH",100,HorizontalAlignment.Left);
listView1.Columns.Add("DATA",100,HorizontalAlignment.Left);


listView2.View = View.Details;
listView2.Columns.Add("Nr.",100,HorizontalAlignment.Left);
listView2.Columns.Add("MESSAGE",100,HorizontalAlignment.Left);
listView2.Columns.Add("LENGTH",100,HorizontalAlignment.Left);
listView2.Columns.Add("DATA",100,HorizontalAlignment.Left);

Das Funktioniert auch so und gibt keine Konflikte. Listview darf dabei
halt noch keine Spalten enthalten.

Die Funktion erwartet als erstes den Spaltentext, dann die Breite und
zum Schluss noch die horizontale Ausrichtung.

von Sven H. (Gast)


Lesenswert?

Hi, vielen Dank!
Das hat mir weitergeholfen.
Wie kann man beim listView immer nur auf eine Zeile zugreifen?
Und zwar stelle ich mir das so vor, wenn ich z.B. immer die gleicher
Can Botschaft mit der selben ID empfange, dann soll nicht immer eine
neue Zeile generiert werden. Nur wenn eine andere ID empfangen wird,
dann soll eine neue zeile erzeugt werden.

von Locutus (Gast)


Lesenswert?

Also erst mal erklär ich noch schnell, wie du eine Zeile ins ListView
einträgst, wenn du das nicht schon weißt.

ListViewItem lvitem = listView1.Items.Add("1"); // Neue Zeileanlegen
und erste Spalte bekommt den Text (in dem Fall "1")
lvitem.SubItems.Add("Message1");  // zweite Spalte der Zeile anlegen
lvitem.SubItems.Add("123");  // dritte Spalte der Zeile anlegen
lvitem.SubItems.Add("DATA1"); // vierte Spalte der Zeile anlegen

Auf die Zeilen zugreifen geht auch ganz einfach.
listView1.Items[0].Text //gibt dir den Text der ersten Spalte in der
ersten Zeile

Dein Problem kann man so lösen:


for (int i=0; i < listView1.Items.Count; i++) // Alle Zeilen
durchgehen
{
 if (listView1.Items[i].Text == "3") return; // Überprüfen des Wertes
der ersten Spalte
}
ListViewItem lvitem = listView1.Items.Add("3");
lvitem.SubItems.Add("Message1");
lvitem.SubItems.Add("123");
lvitem.SubItems.Add("DATA1");

von Sven H. (Gast)


Lesenswert?

Das funktioniert nicht so wie ich es haben will.
Es kommt z.B. die CAN Botschaft mit der ID 15 hex, dann soll keine
weitere Zeile im listView erzeugt werden, sondern die Zeile wird nur
durch die Anzahl der eingetroffenen Botschaften mit der ID 15 hex
hochgezählt.

listView1.View = View.Details;
      listView1.Columns.Add("Nr.",40,HorizontalAlignment.Left);
      listView1.Columns.Add("MESSAGE",80,HorizontalAlignment.Left);
      listView1.Columns.Add("LENGTH",80,HorizontalAlignment.Left);
      listView1.Columns.Add("DATA",180,HorizontalAlignment.Left);
      listView1.Columns.Add("COUNT",70,HorizontalAlignment.Left);


Hier habe ich noch eine weitere Spalte eingefügt.
COUNT gibt an wieviele Botschaften mit der gleichen ID eingetroffen
sind.

von Sven H. (Gast)


Lesenswert?

Das funktioniert nicht so wie ich es haben will.
Es kommt z.B. die CAN Botschaft mit der ID 15 hex, dann soll keine
weitere Zeile im listView erzeugt werden, sondern die Zeile wird nur
durch die Anzahl der eingetroffenen Botschaften mit der ID 15 hex
hochgezählt.

listView1.View = View.Details;
      listView1.Columns.Add("Nr.",40,HorizontalAlignment.Left);
      listView1.Columns.Add("MESSAGE",80,HorizontalAlignment.Left);
      listView1.Columns.Add("LENGTH",80,HorizontalAlignment.Left);
      listView1.Columns.Add("DATA",180,HorizontalAlignment.Left);
      listView1.Columns.Add("COUNT",70,HorizontalAlignment.Left);


Hier habe ich noch eine weitere Spalte eingefügt.
COUNT gibt an wieviele Botschaften mit der gleichen ID eingetroffen
sind.

von Locutus (Gast)


Lesenswert?

Schreib dir einfach eine Methode, der du übergibst, was du alles
brauchst im Listview.
In der gehst du dann alle Listview Zeilen durch und vergleichst die
übergebene Can Botschafts ID mit dem Element der jeweiligen Zeile. Da
du ja hex Zahlen haben willst, musst du die ID noch in einen HexString
Formatieren um die zu vergleichen. Wenn die dann übereinstimmen, dann
zählst du einfach in der Count Spalte der Zeile eins dazu und springst
aus der Funktion raus.

Wenn du alle Zeilen überprüft hast und keine übereinstimmung der Id
gefunden, dann fügst du einfach eine neue Zeile mit den Übergebenen
Daten und Count von 1 ein.

So sieht das ganze dann aus.:

public void NewCanFrame(int id, string message, int length, string
data)
{
 for (int i=0; i < listView1.Items.Count; i++) {
  if (listView1.Items[i].Text == id.ToString("x")){
   int count = Int32.Parse(listView1.Items[i].SubItems[4].Text);
   count++;
   listView1.Items[i].SubItems[4].Text = count.ToString();
   return;
  }
 }

 ListViewItem lvitem = listView1.Items.Add(id.ToString("x"));
 lvitem.SubItems.Add(message);
 lvitem.SubItems.Add(length.ToString());
 lvitem.SubItems.Add(data);
 lvitem.SubItems.Add("1");
}

Und so wird das dann aufgerufen, z.B. beim Buttonklick

private void button1_Click(object sender, System.EventArgs e)
{
 NewCanFrame(15,"Message3",71,"DATA3");
}

von fst (Gast)


Lesenswert?

Mach Dir besser eine HashMap mit der Can-Botschafts-ID als Key und dem
Listview-Index als Value.
das ist aus Perf.-Sicht besser als eine lineare Suche.

Gruß FSt

von Sven H. (Gast)


Lesenswert?

WIe meinst du das fst?
Was ist eine HashMap? Wie könnte ich dies auf mein Problem umsetzen?

von fst (Gast)


Lesenswert?

In C# gibvt es im Namespace System.Collections (evtl. auch als
generischen Typ) den Typ Hashtable.

In einer solchen HashMap legst Du die Verknüpfung "Can-Botschafts-ID"
--> "Listview-Index" folgendermaßen ab:

Als Key wird die "Can-Botschafts-ID" verwendet als Value die
Listview-Index-Nummer. Mit der Fkt. Add hinzufügen. Mit Contains kannst
Du überprüfen ob der Schlüssel enthalten ist.

Lies bitte auch die passenden MSDn-Seiten dazu.

Gruß FSt

von Sven H. (Gast)


Angehängte Dateien:

Lesenswert?

...bin nicht ganz mit dieser Funktion zufrieden.

private void button1_Click(object sender, System.EventArgs e)
    {
     NewCanFrame_transmit(111, 5, "CC");
    }

private void button2_Click_1(object sender, System.EventArgs e)
    {
     NewCanFrame_transmit(111, 3, "AA");
    }

Das Feld wo die Daten stehen, wird hier nicht verändert.
Der Counter wird aber immer um eins hochgezählt.
Ich möchte es aber so haben, das wenn ich das hier wie oben ausführe,
dann soll auch die Daten und die Länge aktualisiert werden.
Erst wenn eine neue ID kommt, dann soll eine neue zeile im ListView
erscheinen.

von Sven H. (Gast)


Lesenswert?

Mir scheint es echt so das in Visual Studio das ganze komplizierter
verpackt ist, als z.B. beim Borland Builder. Unter Borland Builder habe
ich das StringGrid verwendet, da wars einfacher...
Fakt ist ich muss die "NewCanFrame_recieve" Funktion abändern.

von Sven H. (Gast)


Lesenswert?

...ich gehe nochmal näher darauf ein wie ich es genau meine:

Zuerst füre ich die Funktion so aus:
NewCanFrame_transmit(111, 5, "CC");
Erscheinen tut folgendes: Message:111,Length:5,Data:CC,Count:1


Als nächstes für ich die Funktion dann so aus:
NewCanFrame_transmit(111, 3, "AA");
Erscheinen tut folgendes: Message:111,Length:5,Data:CC,Count:2

Beim zweiten verändert sich in meiner ListView nur der Counter.
Wie müsste ich meine Funktion anpassen, dass ich die veränderungen
sehen kann?

von Sven H. (Gast)


Lesenswert?

Hat keiner einen Tip für mich?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.