C# DataSource Manipulieren

roker002

Commander
Registriert
Dez. 2007
Beiträge
2.103
Ich habe eine ganz simple frage auf die ich eigentlich noch gar keine Antwort finden konnte.

Wenn ich Eine Liste habe, die ich mittels ListBox darstellen will, und diese befüllen will, kann man das ja mittels 2 Wege machen.

  1. ListBox.Items.Add(...)
  2. ListBox.DataSource = Collection

Add ist klar... aber wenn ich jetzt eine eigene Collection dafür benutze kommt mir eine Frage auf. Was passiert wenn ich einen Eintrag aus der Collection entferne. Kann man mittels Entfernen eines Eintrags aus der Collection auch den Eintrag aus der ListBox erzwingen? Es werden ja keine Referenzwerte übergeben. Beim ausprobieren funktioniert das ja ganze nicht. D.h. wenn ich während der Laufzeit einen Event auslöse und einen Bestimmten Eintrag lösche, so muss ich den DataSource von ListBox aktualisieren. Ich muss ja dann mehrere Listen verwalten.

Geht das überhaupt einfacher?
 
Es gibt zwei Möglichkeiten:

1. manuell DataBind() aufrufen nachdem du die Datenquelle (deine Collection) geändert hast. - nur in eine Richtung Änderungen von der Collection werden im Control übernommen, andersrum nicht.
2. eine BindingSource verwenden. - beide Richtungen (bin mir nicht sicher ob dies mit ListBox funzt)

/edit2: Wichtig ist das du am besten nur die Daten in der DataSource änderst nicht aber in deinem Control und danach die Datenbindung auffrischt, z.B. über DataBind() oder eben BindingSource...
 
Zuletzt bearbeitet:
ne es geht nicht darum dass ich Datenbank Anbindung habe, sondern das ich mehrere Listen zu verwalten habe. Requery suche gerade gar nicht. Naja aber letztendlich kommt auf das gleiche hinaus wenn man die Daten aus der Datenbank hinzufügen möchte.

Wo genau wird den requery angewandt? Kannst du einen Beispiel geben? Ich habe jetzt herumgegoogelt aber nichts vernünftiges gefunden.
 
Naja erstmal stellt sich die Frage, mit was arbeitest du? WPF oder WinForms, in WPF ist das alles nämlich viel einfacher und ganz anders als in Forms.
 
und wenn das passiert muss ich dennoch bei ObservationCollection und an dem DataSource die Daten korregieren.

Also es geht wirklich nicht dass man die Daten mit einem Schlag gleich behandeln kann. Schade!
 
Es geht per ObservableCollection. Ich hatte das jetzt schon in mehreren Threads erwähnt gehabt. Du bindest diese Collection per DataSource an deine Listbox, wenn Elemente entfernt, hinzugefügt oder geupdatet werden, so wird das an die Listbox weitergeleitet.
 
Wunderlicher weise funktioniert es. Aber ich kann nicht nachvollziehen wieso! Wird es erzwungen den DataSource zu aktualisieren?

Ich habe mal den Code von MSDN geklaut und dann bisschen modifiziert. Das Original ist HIER .

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;

    namespace BindingListOfTExamples
    {
        public partial class Form1 : Form
        {
            private TextBox textBox2;
            private ListBox listBox1;
            private Button button1;
[COLOR="Red"]            private Button button2;[/COLOR]
            private TextBox textBox1;
            Random randomNumber = new Random();

            public Form1()
            {
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.textBox1 = new System.Windows.Forms.TextBox();
                this.textBox2 = new System.Windows.Forms.TextBox();
                this.listBox1 = new System.Windows.Forms.ListBox();
                this.button1 = new System.Windows.Forms.Button();
[COLOR="red"]                this.button2 = new Button();[/COLOR]
                this.textBox1.Location = new System.Drawing.Point(169, 26);
                this.textBox1.Size = new System.Drawing.Size(100, 20);
                this.textBox1.Text = "Bracket";
                this.textBox2.Location = new System.Drawing.Point(169, 57);
                this.textBox2.ReadOnly = true;
                this.textBox2.Size = new System.Drawing.Size(100, 20);
                this.textBox2.Text = "4343";
                this.listBox1.FormattingEnabled = true;
                this.listBox1.Location = new System.Drawing.Point(12, 12);
                this.listBox1.Size = new System.Drawing.Size(120, 95);
                this.button1.Location = new System.Drawing.Point(180, 83);
                this.button1.Size = new System.Drawing.Size(75, 23);
                this.button1.Text = "Add New Item";
                this.button1.Click += new System.EventHandler(this.button1_Click);

[COLOR="red"]                this.button2.Location = new System.Drawing.Point(180, 116);
                this.button2.Size = new System.Drawing.Size(75, 23);
                this.button2.Text = "Delete Item";
                this.button2.Click += new EventHandler(this.button2_Click);[/COLOR]

                this.ClientSize = new System.Drawing.Size(292, 266);
                this.Controls.Add(this.button1);
                this.Controls.Add(this.listBox1);
                this.Controls.Add(this.textBox2);
                this.Controls.Add(this.textBox1);
[COLOR="Red"]                this.Controls.Add(this.button2);[/COLOR]
                this.Text = "Parts Form";
                this.Load += new EventHandler(Form1_Load);

            }

            void Form1_Load(object sender, EventArgs e)
            {
                InitializeListOfParts();
                listBox1.DataSource = listOfParts;
                listBox1.DisplayMember = "PartName";
                listOfParts.AddingNew += new AddingNewEventHandler(listOfParts_AddingNew);
                listOfParts.ListChanged += new ListChangedEventHandler(listOfParts_ListChanged);

            }



            // Declare a new BindingListOfT with the Part business object.
            BindingList<Part> listOfParts;
            private void InitializeListOfParts()
            {
                // Create the new BindingList of Part type.
                listOfParts = new BindingList<Part>();

                // Allow new parts to be added, but not removed once committed.        
                listOfParts.AllowNew = true;
[COLOR="red"]                listOfParts.AllowRemove = true;[/COLOR]

                // Raise ListChanged events when new parts are added.
                listOfParts.RaiseListChangedEvents = true;

                // Do not allow parts to be edited.
[COLOR="red"]                listOfParts.AllowEdit = true;[/COLOR]

                // Add a couple of parts to the list.
                listOfParts.Add(new Part("Widget", 1234));
                listOfParts.Add(new Part("Gadget", 5647));
            }


            // Create a new part from the text in the two text boxes.
            void listOfParts_AddingNew(object sender, AddingNewEventArgs e)
            {
                e.NewObject = new Part(textBox1.Text, int.Parse(textBox2.Text));

            }


            // Add the new part unless the part number contains
            // spaces. In that case cancel the add.
            private void button1_Click(object sender, EventArgs e)
            {
                Part newPart = listOfParts.AddNew();

                if (newPart.PartName.Contains(" "))
                {
                    MessageBox.Show("Part names cannot contain spaces.");
                    listOfParts.CancelNew(listOfParts.IndexOf(newPart));
                }
                else
                {
                    textBox2.Text = randomNumber.Next(9999).ToString();
                    textBox1.Text = "Enter part name";
                }
            }

[COLOR="red"]            private void button2_Click(object sender, EventArgs e)
            {
                if (listBox1.SelectedIndex >= 0)
                {
                    listOfParts.RemoveAt(listBox1.SelectedIndex);
                }
            }[/COLOR]

            void listOfParts_ListChanged(object sender, ListChangedEventArgs e)
            {
                MessageBox.Show(e.ListChangedType.ToString());
            }

            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.Run(new Form1());
            }

        }

        // A simple business object for example purposes.
        public class Part
        {
            private string name;
            private int number;
            public Part() { }
            public Part(string nameForPart, int numberForPart)
            {
                PartName = nameForPart;
                PartNumber = numberForPart;
            }

            public string PartName
            {
                get { return name; }
                set { name = value; }
            }

            public int PartNumber
            {
                get { return number; }
                set { number = value; }
            }
        }
    }

}

Alles was rot ist, wurde von mir hinzugefügt oder geändert!

Wenn man bedenkt, dass es so einfach ist, dann braucht man viel weniger Verwaltungsaufwand. Son mist... wenn ich dass jetzt beginne zu ändern wird es sicher ne weile dauern bis alle Fehler ausgemerzt sind.



EDIT

Ich habe jetzt versucht BindingList in das Programm zu integrieren. Es klappt soweit so gut. Nur wenn ich einen neuen Eintrag hinzufüge, erscheint er mir nicht in der ListBox.
Ich verwende nicht direkt den BindingList, sondern eigene Klasse die von BindingList abgeleitet wurde. Die BindingList wird an sich mit den Informationen gefüllt. Es wird halt nicht beim Listbox aktuallisiert
Im Konstruktor von abgeleitete Klasse steht:

Code:
            this.AllowEdit = true;
            this.AllowNew = true;
            this.AllowRemove = true;
            this.RaiseListChangedEvents = true;

Habe ich noch irgendwas vergessen?


EDIT 2

Das Problem konnte ich mit "BindingList.ResetBinding" lösen. Ich verstehe aber immer noch nicht wieso man ResetBinding aufrufen muss, damit die Werte angezeigt werden.


EDIT 3

Noch ein Problem hat sich bezüglich des BindingList ereignet. Wenn ich die Liste einmal gefüllt habe und die dann versucht mit IList.Clear() zu leeren, so bekomme ich beim Indexer einen Exception, obwohl der Indexer garnicht aufgerufen wird. Es wird versucht einen Eintrag mit Index "-1" zu machen. Ich bin immer noch nicht drauf gekommen woher das ganze kommt.
 
Zuletzt bearbeitet:
Zurück
Oben