Visual C++ MFC Datenbankprogrammierung Tutorial 4


Datenbankbeispiel 4: Hierarchische Darstellung mit TreeControl

Einleitung

In diesem vierten Datenbank-Tutorial zeige ich, wie man mit Visual C++ und MFC (Microsoft Foundation Classes) eine hierarchische Darstellung von Datenbankinhalten in einem TreeControl erstellt. Um diese Anleitung nicht zu lang werden zu lassen, schreibe ich immer nur die Dinge auf, die verändert werden müssen. Bei Codeabschnitten werden die Teile, die von mir verändert wurden, fett geschrieben.


Praktisches Beispiel

Aufgabenstellung

Es sollten vor Beginn dieses Projekts die Maßnahmen getroffen werden, die im Kapitel "Datenbankzugriff Vorbereitung" angegeben sind.

Erstellen Sie ein Programm, welches ein TreeControl (CTreeCtrl) enthält.
In diesem TreeControl werden auf oberer Hierarchieebene die unterschiedlichen Werte des Attributs "BestellteEinheiten" der Tabelle "Artikel" eingetragen. Als Unterpunkte dieser Einträge werden die Werte des Attributs "Artikelname" eingetragen.

Lösung - Schritt für Schritt Anleitung

  1. Neues Projekt anlegen in Visual C++:
  2. Dialog-Design erstellen:
    Es wird nur ein TreeControl (CTreeCtrl) benötigt.
    Screenshot: Dialog-Editor mit TreeControl-Steuerelement

    Um die Linien und Schaltflächen (Plus/Minus-Icons) beim TreeControl zu erhalten, müssen die Eigenschaften des Controls editiert werden:
    Screenshot: TreeControl-Eigenschaften für Linien und Buttons
  3. Membervariable für das TreeControl erstellen:
    Es wird eine Membervariable vom Typ CTreeCtrl für den Zugriff auf das TreeControl benötigt.
    Dazu muss der Klassenassistent geöffnet werden (Strg+W oder View -> ClassWizard).
    Screenshot: ClassWizard für Membervariable des TreeControls
  4. TreeControl bei Programmstart mit Daten füllen:
    Die Hauptlogik befindet sich in der OnInitialUpdate()-Methode, die beim Start des Programms aufgerufen wird:
    void CDb4View::OnInitialUpdate()
    {
        m_pSet = &GetDocument()->m_db4Set;
        CRecordView::OnInitialUpdate();
        GetParentFrame()->RecalcLayout();
        ResizeParentToFit();
    
        CString zwsp;
    
        // Sicherstellen, dass die Datenbank geöffnet ist
        if (!m_pSet->IsOpen())
            m_pSet->Open();
    
        // Sortieren der Tabelle nach "BestellteEinheiten"
        // m_strSort enthält den Teil der SQL-Klausel, der nach ORDER BY kommt
        m_pSet->m_strSort = "[BestellteEinheiten]";
    
        // Neu laden des CRecordSet, um die Sortierung zu aktivieren
        m_pSet->Requery();
    
        // Variable für das Attribut "BestellteEinheiten" des letzten Datensatzes
        int oldanzahl = -1;
        
        // Variable für das TreeControl-Item, unter dem Untereinträge angehängt werden
        HTREEITEM parent;
    
        // Alle Datensätze der Tabelle durchlaufen
        while (!m_pSet->IsEOF())
        {
            // Nur wenn dieser Parent (Bestellte Einheiten) in der TreeControl
            // noch nicht existiert...
            if (oldanzahl != m_pSet->m_BestellteEinheiten)
            {
                // Neue "Bestellte Einheiten" merken
                oldanzahl = m_pSet->m_BestellteEinheiten;
                
                // Wert in String umwandeln
                zwsp.Format("%d", m_pSet->m_BestellteEinheiten);
                
                // Als neuer Parent-Knoten in die TreeControl einfügen
                parent = m_tree.InsertItem(zwsp);
            }
            
            // Artikelname als Child-Element unter dem aktuellen Parent einfügen
            m_tree.InsertItem(m_pSet->m_Artikelname, parent);
            
            // Zum nächsten Datensatz springen
            m_pSet->MoveNext();
        }
    
        // Diese Einfügemethode funktioniert nur, weil die Datensätze
        // vorher nach "BestellteEinheiten" sortiert wurden
    }
    Wichtiger Hinweis:
    Der Algorithmus funktioniert nur, weil die Datensätze vorher nach dem Feld "BestellteEinheiten" sortiert wurden. Dadurch werden alle Artikel mit der gleichen Bestellmenge hintereinander im RecordSet angeordnet, was die hierarchische Gruppierung im TreeControl ermöglicht.

    Schlüsselkonzepte im Code:

  5. Projekt kompilieren und testen: Die Anwendung zeigt jetzt Artikel hierarchisch gruppiert nach ihrer Bestellmenge in einem TreeControl an.

Erweiterungsmöglichkeiten:
- Mehrere Hierarchieebenen (z.B. Kategorie → Bestellmenge → Artikel)
- Icons für verschiedene Elementtypen im TreeControl
- Drag & Drop-Funktionalität für TreeControl-Elemente
- Kontextmenüs für TreeControl-Elemente
- Ein-/Ausklappen aller Ebenen mit einem Klick

Programmierecke.NET