Laden...

DataGridViewCheckBoxColumn und Datenbindung

Erstellt von Seebär vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.400 Views
S
Seebär Themenstarter:in
48 Beiträge seit 2011
vor 12 Jahren
DataGridViewCheckBoxColumn und Datenbindung

Hallo,

ich habe eine DataSet mit zwei DataTables (Aufträge, Unteraufträge), die in einer 1:n-Beziehung miteinander stehen.

Die Daten selber werden mit BindingSources verwaltet:


aufträgeBindingSource.DataSource = ds;
aufträgeBindingSource.DataMember = "Aufträge";
unterAufträgeBindingSource.DataSource = aufträgeBindingSource;
unterAufträgeBindingSource.DataMember = "FK_Aufträge_AuftragsID_UnterAufträge_AuftragsID";

Nun gebe ich ein einem DataGridView die Unteraufträge aus, indem ich die DataSource auf die BindingSource mit den Unteraufträgen setze.

Zusätzlich möchte ich die Felder 'AuftragsNummer' und 'Ist Abgeschlossen' aus der Tabelle Aufträge mit anzeigen lassen.

Das klappt mit der AuftragsNummer auch gut, da ich hier eine DataGridViewComboBoxColumn verwenden kann:


DataGridViewComboBoxColumn comboboxColumn = new DataGridViewComboBoxColumn();
comboboxColumn.DataPropertyName = "AuftragsID";
comboboxColumn.HeaderText = "Auftragsnummer";
comboboxColumn.Name = "Auftragsnummer";
comboboxColumn.DataSource = aufträgeBindingSource;
comboboxColumn.ValueMember = "AuftragsID";
comboboxColumn.DisplayMember = "AuftragsNummer";
comboboxColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
comboboxColumn.SortMode = DataGridViewColumnSortMode.Automatic;
comboboxColumn.ValueType = typeof(Int32);
dgvUnterAufträge.Columns.Insert(0, comboboxColumn);

Das Feld 'Abgeschlossen' ist jedoch ein BIT-Feld, welches ich gerne mit einer DataGridViewCheckBoxColumn darstellen würde.

Da funktioniert das Szenario von oben aber leider nicht, da die Eigenschaften DataSource, ValueMember und DisplayMember nicht verfügbar sind.

Auch der Versuch

                checkBoxColumn = new DataGridViewCheckBoxColumn();
                checkBoxColumn.DataPropertyName = "Parent.[Ist Abgeschlossen]";
                checkBoxColumn.HeaderText = "Ist abgeschlossen";
                checkBoxColumn.Name = "Ist abgeschlossen";
                checkBoxColumn.SortMode = DataGridViewColumnSortMode.Automatic;
                checkBoxColumn.ValueType = typeof(bool);

führt leider nicht zum Erfolg.

Hat jemand eine Idee, wie ich Datenbindung an eine DataGridViewCheckBoxColumn hinbekomme?

Vielen Dank im Voraus!

U
58 Beiträge seit 2011
vor 12 Jahren

vielleicht keine DIREKTE antwort auf deine frage, aber ein vorschlag:
ich würde es so machen/mache es immer so:

erstell dir eine klasse COrder, die einen auftrag repräsentiert:


public class COrder
{
    internal int _id;
    public int ID
    {
        get { return _id; }
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    private bool _finished;
    public bool Finished
    {
        get { return _finished; }
        set { _finished= value; }
    }

    //...

    public COrder()
    {

    }
}

erstell eine klasse (z.b. eine statische klasse "CData"), die die ganze datenbanklogik enthält und dir auf wunsch eine menge von aufträgen als objekte der klasse COrder zurückgibt.

z.b. mit so einer methode:


public static List<COrder> GetAllOrders()
    {
        List<COrder> orders = new List<COrder>();

        try
        {
            using (SqlConnection connection = new SqlConnection(conStr))
            {
                connection.Open();
                SqlCommand command = connection.CreateCommand();
                command.CommandText = "SELECT * FROM Aufträge";
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        COrder order = new COrder();
                        order._id = Convert.ToInt32(reader["ID"]);
                        order.Name = reader["Name"].ToString();
                        order.Finished = Convert.ToBoolean(reader["Ist_Abgeschlossen"].ToString());
                        orders.Add(order);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            //event-handling 
        }
        return orders;
    }

jetzt kannst du einfach im designer hergehen und dein datagridview ohne eine zeile code so anpassen wie du es magst.

kleines kästchen oben rechts im datagridview --> spalten bearbeiten
im fall von oben 3 spalten hinzu, 2 DataGridViewTextBoxColumns und eine DataGridViewCheckBoxColumn.

DataPropertyName ist jetzt - wie der name es erahnen lässt - das property deiner klasse COrder, das du in der spalte anzeigen möchtest. bei der CheckBoxColumn wäre es "Finished".

jetzt einfach das datagridview mit deinen objekten füllen:


DataGridView1.DataSource = CData.GetAllOrders();

das war's.

sieht für mir nach der saubereren lösung aus, weil man a) mengen von objekten verwendet und b) nicht per code aufgaben vom designer erledigt.

mit den comboboxen geht das natürlich genauso..

S
Seebär Themenstarter:in
48 Beiträge seit 2011
vor 12 Jahren

Hallo uNki,

vielen Dank für deine Antwort - das klappt schon sehr gut!

5.299 Beiträge seit 2008
vor 12 Jahren

Ich würde im Dataset eine berechnete Spalte einrichten, die per Expression auf den Bool-Wert des übergeordneten Datensatzes verweist.
So eine DataColumn hat keine Rückwirkung auf die Datenbank, und das DGV generiert hierfür standardmäßig CheckboxColumns.

gugge DataExpressions

Der frühe Apfel fängt den Wurm.