Hi,
ich habe ein merkwürdiges Problem. Und zwar verwende ich in meiner Anwendung ein ListView. Wenn man ein Item darin anklickt mit der rechten Maustaste, dann öffnet sich ein Kontextmenü. Darin kann man das aktuell angeklickte Item löschen, indem ich die ganze Liste leere und aus einem string Array die Items neu reinschreibe nur eben ohne das vorher angeklickte. Das funktioniert auch gut, allerdingt klappt es immer beim letzten Item nicht.
Normalerweise will er das gleiche Item wieder markieren, wie vorher. Das ist aber nichtmehr da,also markiert er normalerweise das Item darunter. Das geht beim letzten aber nicht, wil es darunter keins gibt,also bricht er ab und gubt einen Fehler aus.
Was kann ich da machen?
==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================
Hmm also weiß jetzt auch nichtmehr was das sein könnte. Mache es jetzt anders. Ich lösche das Item aus der ListView mit ListView.Item[index].Remove(); aber es kommt immernoch die Fehlermeldung:
Argument liegt auserhalb des gültigen Bereichs ... ListViewItemCollection.get_Item(Int 32 displayIndex)
==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================
die Fehlermeldung sagt, dass dein "index" entweder zu klein ist, also < 0, oder eher zu groß > listView1.Items.Count - 1
ja das weiß ich ja, aber was kann ich dagegen tun?
==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================
8o 8o 8o
vor der Anweisung
ListView.Item[index].Remove()
prüfen, ob index im gültigen bereich liegt.
oder reden wir aneinander vorbei?
Das Problem ist, zum Zeitpunkt der Überprüfung ist der index noch im Gültigen Bereich.
==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================
dann wird beim löschen irgendein Ereignis gefeuert, bei dem du diese Prüfung nicht machst.
prüfe noch mal die Listview-Ereignisse.
ListView hat nur das KeyDown-Ereignis um das Kontextmenü zu öffnen. Hier mal der ganze Quelltext dazu. Ich will nur das letzte Item per Kontextmenü löschen können wenn ich darauf klicke.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Drawing2D;
namespace test
{
/// <summary>
/// Zusammenfassung für Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.ListView listView1;
private System.Windows.Forms.ContextMenu contextMenu1;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.Button button1;
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Erforderlich für die Windows Form-Designerunterstützung
//
InitializeComponent();
//
// TODO: Fügen Sie den Konstruktorcode nach dem Aufruf von InitializeComponent hinzu
//
}
/// <summary>
/// Die verwendeten Ressourcen bereinigen.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Vom Windows Form-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
this.listView1 = new System.Windows.Forms.ListView();
this.contextMenu1 = new System.Windows.Forms.ContextMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// listView1
//
this.listView1.Location = new System.Drawing.Point(64, 32);
this.listView1.MultiSelect = false;
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(208, 208);
this.listView1.TabIndex = 0;
this.listView1.View = System.Windows.Forms.View.List;
this.listView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listView1_KeyDown);
this.listView1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.listView1_MouseDown);
//
// contextMenu1
//
this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1});
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.Text = "löschen";
this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
//
// button1
//
this.button1.Location = new System.Drawing.Point(240, 272);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(72, 24);
this.button1.TabIndex = 1;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(328, 318);
this.Controls.Add(this.button1);
this.Controls.Add(this.listView1);
this.Name = "Form1";
this.Text = "Form1";
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// Der Haupteinstiegspunkt für die Anwendung.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
}
private void listView1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
}
private void listView1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if(e.Button == MouseButtons.Right)
{
Point p = new Point(e.X,e.Y);
this.contextMenu1.Show(this.listView1,p);
}//if
}
private void menuItem1_Click(object sender, System.EventArgs e)
{
try
{
int index = this.listView1.FocusedItem.Index;
this.listView1.SelectedItems.Clear();
this.listView1.Items[index].Remove();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button1_Click(object sender, System.EventArgs e)
{
this.listView1.Items.Add("test");
}
}
}
Probierst ruhig mal bei dir aus. Alle gehen, nur das letzte nicht.
==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================
ich gebe zu, bei mir kommt auch diese fehlermeldung auch. sieht nach einem bösen Bug aus.
abhilfe:
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
abonnieren und behandeln
Wie meinst du das? Was soll ich damit machen?
==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================
also:
bei mir passiert Folgendes: wenn ich den letzten Eintrag in der Liste lösche. kommt die gleiche Exception, wie bei dir auch. Diese Exception wird aber von dem try..catch Block hier:
private void menuItem1_Click(object sender, System.EventArgs e)
{
try
{
int index = this.listView1.FocusedItem.Index;
this.listView1.SelectedItems.Clear();
this.listView1.Items[index].Remove();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
nicht abgefangen
also habe ich Behandlung für Application.ThreadException Ereignis eingerichtet. Dort wird die Exception, welche bei Remove entsteht, abgefangen und kann behandelt werden.
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.ListView listView1;
private System.Windows.Forms.ContextMenu contextMenu1;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.ComponentModel.Container components = null;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
private void InitializeComponent()
{
System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem("1");
System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem("2");
System.Windows.Forms.ListViewItem listViewItem3 = new System.Windows.Forms.ListViewItem("3");
System.Windows.Forms.ListViewItem listViewItem4 = new System.Windows.Forms.ListViewItem("4");
System.Windows.Forms.ListViewItem listViewItem5 = new System.Windows.Forms.ListViewItem("5");
this.listView1 = new System.Windows.Forms.ListView();
this.contextMenu1 = new System.Windows.Forms.ContextMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
this.SuspendLayout();
this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1});
this.listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
listViewItem1,
listViewItem2,
listViewItem3,
listViewItem4,
listViewItem5});
this.listView1.Location = new System.Drawing.Point(0, 0);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(416, 168);
this.listView1.TabIndex = 0;
this.listView1.View = System.Windows.Forms.View.Details;
this.listView1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.listView1_MouseDown);
this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1});
this.menuItem1.Index = 0;
this.menuItem1.Text = "Delete";
this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click_1);
this.columnHeader1.Width = 200;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.SystemColors.Control;
this.ClientSize = new System.Drawing.Size(419, 404);
this.Controls.Add(this.listView1);
this.Name = "Form1";
this.Text = "Form1";
this.TransparencyKey = System.Drawing.Color.FromArgb(((System.Byte)(0)), ((System.Byte)(192)), ((System.Byte)(0)));
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
private void menuItem1_Click_1(object sender, System.EventArgs e)
{
try
{
int index = this.listView1.FocusedItem.Index;
this.listView1.SelectedItems.Clear();
this.listView1.Items[index].Remove();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void listView1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if(e.Button == MouseButtons.Right)
{
Point p = new Point(e.X,e.Y);
this.contextMenu1.Show(this.listView1,p);
}
}
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
}
}
Also das ist zwar nicht die schönste Lösung, aber es Hilft 😉
Scheinbar gibt es da wohl auch nicht viele Möglichkeiten diesen Fehler zu umgehen. Der Bug steck wohl eher im Steuerelement von Microsoft,da haben die wohl vergessen die Situation zu behandeln, denn ich denke mal so ungewöhnlich ist es nicht, wenn ich per Maustaste und Kontextmenü einen Eintrag(Item) löschen will und da darf es auch nichts ausmachen,wenn es das letzte Item ist.
==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================
Wie wär`s mit:
foreach(ListViewItem item in listView1.SelectedItems)
{
listView1.Items.Remove(item);
}
Gernot Melichar
Das funktioniert nicht, in einer foreach-Schleife kann man keine Elemente aus einer Collection entfernen.
// Edit: ist Quatsch, ist ja eine andere Collection.
Ist auch eine Möglichkeit mehrere Items gleichzeitig zu markieren
und zu löschen.
Gernot Melichar
Hallo,
denke das ist kein Bug! Ich meine das ListView ist nur (wies der Name schon sagt), zum anzeigen gedacht, nicht um Daten zu speichern. Dafür gibts ja Datagrid!
Man sollte das ListView an einen Datensatz binden und mit hilfe des ListViews diesen dann manipulieren!
MfG
Bewareofthis
Genau das passiert ja bei mir auch. Ich lösche im Hintergrund einen Eintrag aus einer Datenbank, und deswegen möchter ich aber auch den Eintrag aus dem ListView weg haben, dass ist ja schließlich nur zum anzeigen der Datengedacht.
==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================
Lösche dafür nicht das ListView Item, sondern das aus der Datenbank und lies das ListView danach neu ein.