Seltsame IndexOutOfRangeException mit BindingSource

27/06/2008 - 15:16 von christoph.doerfler | Report spam
Hallo,

ich habe einen seltsamen Fehler, den ich nicht recht verstehe - über
Hinweise bin ich dankbar:
Ich binde eine ListBox an eine BindingSource, die ein DataMember einer
Datenquelle wrappt. Wenn ich das CurrentItem dieser Datenquelle àndere
bekomme ich unter sehr speziellen Bedingungen eine
IndexOutOfRangeException. Voraussetzung ist, dass das DataMember eine
leere Collection ist und die Abfrage des ListBox.SelectedItems in der
OnDrawItem()-Methode der ListBox stattfindet.

Ich habe das Problem zum Nachstellen isoliert. Man braucht eine Form,
eine ListBox und einen Button.
Interessant für mich:
- Warum tritt das Problem genau in der OnDrawItem()-Methode auf
(siehe in der Button_Click()-Methode: dort funktioniert es)
- Warum passiert es nur, wenn die gebundene Liste keine Elemente hat
(Einkommentieren einer Zeile im Konstruktor verhindert die
Exception)
Nach Auftreten der Exception kann man die Anwendung weiterlaufen
lassen. Der Fehler tritt dann nicht mehr auf.

Das Problem tritt auch bei komplexerer Implementierung der Datenquelle
(mit IBindingListView, ITypedList) auf. Es liegt nicht an nicht
weitergereichten Events, so weit ich das nachvollziehen kann.

Ich freue mich über jede Erklàrung,
Christoph

public partial class Form1 : Form
{
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.Button button1;

private readonly BindingSource m_BindingSource;
private readonly Collection<Item> m_Items = new
Collection<Item>();

public Form1()
{
InitializeComponent();

listBox1.DrawMode = DrawMode.OwnerDrawFixed;
listBox1.DrawItem += ListBox1_OnDrawItem;

m_Items.Add( new Item() );
m_Items.Add( new Item() );
m_Items[0].SubItems.Add( "test" );

// Uncomment and no IndexOutOfRangeException is
thrown
//m_Items[1].SubItems.Add( "test" );

m_BindingSource = new BindingSource( m_Items, null );
listBox1.DataSource = new
BindingSource( m_BindingSource,
"SubItems" );
}

private void ListBox1_OnDrawItem( object sender,
DrawItemEventArgs
e )
{
e.DrawBackground();
using( Brush brush = new SolidBrush( e.ForeColor ) )
{

e.Graphics.DrawString( listBox1.Items[e.Index].ToString(),
listBox1.Font, brush, e.Bounds.Left, e.Bounds.Top );
}

// Working
object working ( (BindingSource)listBox1.DataSource ).Current;

// Throws an IndexOutOfRangeException
object notWorking = listBox1.SelectedItem;
}

private void button1_Click( object sender, EventArgs e )
{
m_BindingSource.Position++;

// Here working
object working = listBox1.SelectedItem;
}

}

public class Item
{
private readonly Collection<string> m_SubItems = new
Collection<string>();

public Collection<string> SubItems
{
get { return m_SubItems; }
}
}
 

Lesen sie die antworten

#1 Frank Dzaebel
27/06/2008 - 20:30 | Warnen spam
Hallo Christioph,

m_BindingSource = new BindingSource(m_Items, null);
listBox1.DataSource = new BindingSource(m_BindingSource, "SubItems");



Hier kapselst Du doppelt, was normal nicht notwendig
ist und zu Deinem Problem führt.
Ich denke, Du meinst eigentlich:

m_Items.Add(new Item()); m_Items.Add(new Item());
m_Items[0].SubItems.Add("test1");
m_Items[0].SubItems.Add("test2");
m_BindingSource = new BindingSource(m_Items, "SubItems");
listBox1.DataSource = m_BindingSource;

PS. lass die ungarische Notation auch für Membervariablen weg:

[Qualitàtssicherung für verwalteten Sourcecode]
http://msdn.microsoft.com/de-de/lib...78146.aspx
(... "verwenden Sie camelCasing ... für Parameter, lokale Variablen
und die privaten oder geschützten Variablen einer Klasse")


ciao Frank
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET

Ähnliche fragen