Softwareprogrammierung mit csharp (C#)

Einleitung

Voraussetzungen für Csharp

Welche Voraussetzungen Sie erfüllen müssen, bevor Sie mit der Programmierung in Csharp beginnen können:

  • IDE (Entwicklungsumgebung)
  • .Net Framework
  • Grundkenntnisse in der Programmierung empfohlen, jedoch nicht zwingend notwendig

 

IDE

Als IDE empfiehlt sich das kostenlose Tool Visual Studio Community.

  Visual Studio Community herunterladen

 

.Net Framework

Das .Net Framework ist die Runtime und muss auf dem Computer installiert sein. Ab Windows 7 sollte dies automatisch mit den Windows Updates geschehen. Spätestens bei der Installation von Visual Studio, wird diese aber mitinstalliert.

Ein manueller Download ist hier möglich.

  .Net Framework herunterladen

0

0

Back To Top

Grundlagen

Neues Projekt in Visual Studio anlegen

Neues Projekt erstellen

Um ein neues Projekt in Visual Studio zu erstellen klickt Ihr auf Datei – Neues Projekt…. Alternativ könnt Ihr das mit der Tastenkombination Strg + Umschalt + N machen.

Nun öffnet sich ein neues Fenster, indem Ihr den Projekttypen auswählen müsst.

Links wird die Programmiersprache gewählt. Je nachdem welche Ihr installiert habt, erscheint hier unter anderem Visual C#, Visual C++ usw.

Wir wählen hier Visual C# (csharp). Nun muss noch zwischen den Projekttypen gewählt werden. Je nach gewählter Programmiersprache steht hier eine andere Auswahl zur Verfügung.

Windows-Form-Anwendung

Projekte, welche mit diesen Typ erstellt werden, nutzen den Style des installierten Windows. Hier ist nur bedingt eine Anpassung des Erscheinungsbildes möglich.

WPF-Anwendung (Windows Presentation Form)

Hier kann das Design beliebig angepasst werden. Es gibt auch eine Vielzahl an UI Toolkits, welche installiert werden können. Der WPF Typ nutzt XML zum Anpassen des Designes.

Fürs Erste entscheiden wir uns für eine Windows-Form-Anwendung.

0

0

Back To Top

Arbeiten mit Visual Studio

Visual Studio

(1) Menüleiste

Enthält alle wichtigen Menüpunkte, wie Speichern / Öffnen, Einstellungen usw.

(2) Werkzeugkasten

Hier findet Ihr alle Objekte, welche Ihr in eurem Projekt benutzen könnt. Diese lassen sich einfach in den Ansicht-Designer hineinziehen („drag and drop“). Dabei wird zwischen zwei Typen unterschieden.

  • drawables (Objekte, welche in der Form sichtbar sind)
  • virtuell (Objekte, welche nicht in der Form sichtbar sind)

Als sichtbare Objekte zählen unter anderem Buttons, Labels usw.. Als nicht sichtbare, sprich virtuelle Objekte gilt zum Beispiel der BackgroundWorker.

(3) Ansicht-Designer

Hier findet das eigentliche Gestalten der Form statt. Die Objekte können je nach Dock frei bewegt werden und an die gewünschte Position gebracht werden. Besser ist jedoch das Benutzen von TableLayoutPanel Objekten. Dies ermöglicht die Erstellung eines Raster (Tabelle) in welches Objekte angeordnet werden können.

(4) Eigenschaften für gewähltes Objekt

 

(5) Projektmappe

 

0

0

Back To Top

Datenbanken

MySQL Datenbank in csharp verwenden

Datenbanken

Oft erfordert eine Softwarelösung das Speichern von Daten in einer zentralen Datenbank. Visual Studio liefert für MS SQL Datenbanken eine eingebaute Bibliothek mit, jedoch nicht für MySQL Datenbanken. Dazu ist ein sogenannter Connector notwendig. Dieser kann kostenlos heruntergeladen werden.

Download

MySQL Connector (DotNet) (2 Downloads)

Ladet euch den Connector für euer Betriebssystem herunter und installiert diesen.

Verweis in VS Projekt hinzufügen

Wenn der Connector installiert ist, kann dieser in einem Visual Studio Projekt verwendet werden. Dazu muss erst ein Verweis erstellt werden. Dazu führt Ihr einfach einen rechten Mausklick auf Verweise in eurer Projektmappe aus und wählt Verweis hinzufügen…

Nun sucht unter Assembly nach „MySQL“ und wählt folgende Elemente aus.

Mit OK werden diese eurem Projekt hinzugefügt.

Abschließend muss der Verweis noch in eurer jeweiligen Klasse gemacht werden.

//MYSQL CONNECTOR
using MySql.Data;
using MySql.Web;

 

0

0

Back To Top

Entwickeln einer Datenbank mit Frontend in csharp

Ich werde Ihnen hier anhand eines einfachen Beispieles zeigen, wie Sie eine MySQL Datenbank & eine Frontend-Softwarelösung mit csharp (C#) entwickeln.

Ansatz

In diesem Beispiel möchten wir eine Cocktail-Rezept-Datenbank entwickeln. Dazu benötigen wir

  • eine leere MySQL Datenbank
  • ein SQL Script zum Erstellen der Tabellen und Relationen
  • eine Frontend Lösung zur Eingabe und Suche von Rezepten

Die Datenbank

Am einfachsten ist es, auf seinen eigenen PC eine MySQL Datenbank zu hosten. Wenn Sie ein NAS von Synology [Affiliate Link] besitzen, können Sie auch von dort aus eine Datenbank bereitstellen. Folgend finden Sie kostenlose SQL Server zum Herunterladen und Installieren auf Ihrem PC.

Kostenlose SQL Server herunterladen

Die Datenbankstruktur

Da das Augenmerk auf die Programmierung des Frontend liegt, gehe ich hier nur bedingt in die Tiefe. Wenn Sie mehr über SQL Scripting lernen wollen, dann finden Sie ein weiteres Tutorial hier.

Neue Datenbank erstellen

Führen Sie folgendes SQL Script in Ihrer Datenbank aus (z.b. phpMyAdmin). Dies erstellt eine neue Datenbank und setzt diese auf aktiv.

CREATE DATABASE Cocktail_Rezepte;
USE Cocktail_Rezepte;

 

Was wollen wir speichern?

Zu Beginn müssen wir uns überlegen, was wir eigentlich in der Datenbank speichern wollen.

  • Name des Cocktails
  • Eine kleine Beschreibung
  • Zutaten mit der entsprechenden Menge
  • Ein Bild bzw. Bilder des Cocktails

Tabellen

Zunächst erstellen wir die Tabelle für die Cocktails.

CREATE TABLE Cocktails
(
ID int AUTO_INCREMENT,
Name varchar(128),
Beschreibung varchar(512),
PRIMARY KEY (ID)
);

 

Als Primärschlüssel wurde hier ein Surrogatschlüssel gewählt. Dies ist eine nichts-sagende ID. Würden wir hier den Namen als Primärschlüssel wählen, dann könnte ein Cocktail nur einmal in der Datenbank angelegt werden. Aber es gibt ja viele verschiedene Rezepte für einen Cocktail.

CREATE TABLE Zutaten
(
Zutat varchar(128),
PRIMARY KEY (Zutat)
);

Nun legen wir die Tabelle für die Zutaten an. Die Zuweisung von Zutat(en) und Menge erfolgt in einer weiteren Tabelle. Des Weiteren benötigen wir auch noch eine Tabelle für die Einheiten. Diese legen wir wie folgt an.

CREATE TABLE Einheiten
(
Einheit varchar(32),
Einheitstext varchar(128) NOT NULL,
PRIMARY KEY (Einheit)
);

Grundlegende Einheiten können wir gleich anlegen.

INSERT INTO Einheiten (Einheit, Einheitstext) VALUES
('mg', 'Milligram'),
('g', 'Gramm'),
('ml', 'Milliliter'),
('cl', 'Centiliter'),
('l', 'Liter')
;

Natürlich könnten alle Informationen auch in einer Tabelle angelegt werden, das entspricht aber nicht den Grundlagen der Datenbankentwicklung. Es gilt, alles auszulagern, was kein Alleinstellungsmerkmal der zu speichernden Daten ist. Des Weiteren ergeben sich danach einige Vorteile. Aber später mehr.

Zum Schluss legen wir nun die Tabelle an, welche all unsere Daten vereinigt.

CREATE TABLE Cocktail_Zutataten
(
Cocktail_ID int,
Zutat varchar(128),
Menge int NOT NULL,
Einheit varchar(32) NOT NULL,
PRIMARY KEY (Cocktail_ID, Zutat),
FOREIGN KEY (Cocktail_ID)
REFERENCES Cocktails(ID)
ON UPDATE CASCADE
ON DELETE CASCADE
,
FOREIGN KEY (Einheit)
REFERENCES Einheiten(Einheit)
ON UPDATE CASCADE
ON DELETE RESTRICT
);

 

Da wir Eigenschaften, wie die Einheit, ausgelagert haben, müssen wir in dieser Tabelle ein Verweis (FOREIGN KEY, Fremdschlüssel) anlegen, welcher auf die Tabelle zeigt, welche die Einheit erhält. Dies hat den Vorteil, dass nur Einheiten verwendet werden können, welche auch wirklich angelegt sind. Das verhindert verschiedene Schreibweisen von gleichen Mengeneinheiten.

Übersicht

Eure Datenbank sollte nun wie folgt aussehen und diese Tabellen enthalten.

0

0

Back To Top

Entwickeln des Frontends und öffnen der Datenbankverbindung

Da die Datenbank nun steht, können wir uns um die Benutzeroberfläche (das Frontend) kümmern. Dazu legen wir ein neues Projekt in Visual Studio an.

Projekt anlegen

In diesem Beispiel nenne ich das Projekt schlicht „CocktailRezepte“. Wie Ihr euer Projekt nennt, ist natürlich euch überlassen.

Was wollen wir Anzeigen / Eingeben?

Nun stellt sich uns die Frage, was wollen wir im Frontend alles machen? Folgendes wollen wir integrieren.

  • Ansicht aller Rezepte mit Suchfunktion
  • das anlegen / bearbeiten von Rezepten
  • das Löschen von Rezepten

Gestaltung des Frontends

Beginnen wir mit dem Anzeigen aller Rezepte. Dafür bietet sich das DataGridView Objekt an.

Um eine Struktur zu erhalten, ziehen wir zuerst ein TableLayoutPanel Objekt in die Form, und dann das DataGridViewObjekt. Ihr solltet dann folgende Ansicht erhalten.

Nun passen wir das Layout ein wenig an. Dazu markieren Sie bitte das TableLayoutObjekt und klicken Sie auf den kleinen Pfeil, welcher im oberen, rechten Eck erscheint.

Hier wählt Ihr Zeilen und Spalten bearbeiten aus. Nun könnt Ihr vorhandene Zeilen / Spalten bearbeiten oder neue hinzufügen. Machen Sie bitte folgende Änderungen

Spalten

  • Spalte1: 100%
  • Spalte2: 140px

Zeilen

  • Zeile1: 30px
  • Zeile2: 100%

Das Ergebnis sollte nun wie folgt aussehen.

Jetzt wählen wir das DataGridView Objekt aus und passen die Position im Layout an. Dies könne Sie in den Objekteigenschaften machen, welche erscheinen wenn ein Objekt markiert ist.

Setzen Sie hier folgende Eigenschaften:

  • ColumnSpan: 2
  • Dock: Fill
  • Row: 1
  • Entwurf – (Name): dgvCocktails

Dies wird das DataGridView Objekt neu positionieren. Eure Form sollte nun so aussehen.

Fügen Sie nun einen neuen Button in der linken oberen Ecke hinzu. Nennen Sie diesen btnSuchen und geben Sie diesem den Text „Suchen“. Dieser wird später unseren Suchdialog öffnen.

Programmierung des Frontends

Das grobe Design steht soweit. Nun geht es an die Programmierung und den Aufbau der Datenbankverbindung. Dazu wechseln wir in die Code-Ansicht (Taste F7).

Verweise hinzufügen

Fügen Sie die Verweise MySql.DataMySql.Data.MySqlClient & MySql.Web hinzu. Die Schritte dafür finden Sie hier. Anschließend binden Sie die Funktionen des MySQL Connectors mit der using Anweisung in Ihr Projekt ein.

//MYSQL CONNECTOR
using MySql.Data;
using MySql.Data.MySqlClient;
using MySql.Web;

Nun können wir ein neues Objekt MySqlConnection über den Konstruktor der Form erstellen.

public MySqlConnection Connection = new MySqlConnection();

Des Weiteren deklarieren wir folgende Variablen, welche die Verbindungsdaten unserer Datenbank enthalten werden.

private string db_server = "IHR_SERVER";  //localhost, wenn Sie die Datenbank auf Ihrem PC betreiben
private string db_user = "DATENBANKBENUTZER";
private string db_password = "PASSWORT";
private string db_name = "Cocktail_Rezepte";
private string db_port = "3307";

Im Konstruktor der Form erstellen wir nun den ConnectionString, welcher die Verbindungsparameter an das MySqlConnection Objekt übergibt.

 Connection.ConnectionString = "Server=" + db_server + ";Database=" + db_name + ";Uid=" + db_user + ";Pwd=" + db_password + ";Port=" + db_port + ";"
+ "Encrypt=false;";

Wechselt nun zurück in den Ansicht-Designer und wechselt in den Eigenschaften der Form auf Ereignisse (Form muss ausgewählt sein). Das könnt Ihr durch das Klicken auf den „Blitz“.

Scrollt zum Ereignis „Shown“ und macht einen Doppelklick im leeren Textfeld daneben. Das erstellt ein neues Event. Hier bauen wir die Verbindung zur Datenbank auf.

 private void Form1_Shown(object sender, EventArgs e)
{
try
{
Connection.Open();
}
catch(MySqlException exc)
{
MessageBox.Show(exc.Message, "Datenbankfehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
this.Close();
}
}

Wir versuchen (try) eine Datenbankverbindung zu öffnen. Sind die Daten korrekt, wird eine Verbindung geöffnent und es könen SQL Befehle ausgeführt werden. Sind jedoch die Verbinungsparameter nicht korrekt, dann wird eine Ausnahme geworfen. Diese fangen (catch) wir auf und geben eine Fehlermeldung aus. Danach wird das Tool geschlossen. Machen wir das nicht, würde bei einen Fehler die Applikation kommentarlos abstürzen.

Projektübersicht

Euer Projekt sollte nun so aussehen.

0

0

Back To Top

Datenbank Abfragen und Daten anzeigen

Daten aus Datenbank abfragen

Nun können wir beginnen Daten von der Datenbank abzufragen. Dazu basteln wir uns eine Funktion, welcher wir folgende Parameter übergeben:

  • Tabellenname
  • Filter (optional)

Code-Snippet

 public DataTable DatenVonTabelle(string Tabelle, string Filter = "")
{
DataTable dt = new DataTable();
try
{
if (Connection.State != ConnectionState.Open)
Connection.Open();
String abfrage= "SELECT * FROM " + Tabelle + (Filter == "" ? String.Empty : " WHERE " + Filter);
MySqlDataAdapter msda = new MySqlDataAdapter(abfrage, Connection);
msda.Fill(dt);
Connection.Close();
}
catch (MySqlException e)
{
MessageBox.Show(e.Message, "Datenbankfehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (Connection.State == ConnectionState.Open) Connection.Close();
}
return dt;
}

Diese Funktion versucht Daten von der Datenbank abzufragen. Ist die Verbindung geschlossen, so wird diese geöffnet. Der „abfrage“ String enthält den SQL Befehl um Daten aus einer Tabelle abzufragen. Optional wird dieser mit einem Filter erweitert, wenn wir zum Beispiel nur bestimmte Daten abfragen wollen. Das Ergebnis landet dann in einer Datentabelle (DataTable Objekt), welches direkt einem DataGridView Objekt zugewiesen werden kann.

Da wir beim Start gleich unsere Cocktails sehen wollen, erweitern wir unser Form1_Shown Event mit folgendem Code. Dieser sollte unter dem „Connection.Open()“ Teil eingefügt werden.

dgvCocktails.DataSource = DatenVonTabelle("Cocktails");

Starten wir nun unser Tool, bekommen wir folgende Ansicht.

Beispieldaten einspielen

Da aktuell noch keine Daten in der Datenbank sind, erhalten wir nur die Spalten und eine leere Zeile. Um die Anzeige besser testen zu können, fügen wir schon Mal zwei Cocktails via SQL hinzu. Gebt dazu folgenden Befehl ein.

SQL-Befehl

INSERT INTO Cocktails (Name, Beschreibung) VALUES
('Touchdown', 'Alle Zutaten bis auf die Grenadine im Shaker mit Eis etwa 15 sec. shaken. Anschließend einen Spirtzer Grenadine und Zitronensaft hinzugeben. Fertig!' ),
('Caipirinha', 'Die Limetten klein herschneiden, am besten vierteln und in das Glas geben. Den Rohrzucker darüber streuen und mit einen Stößel zerdrücken.
Den Cachaça dazugeben und alles gut vermischen. Geben Sie anschließend noch Eis dazu.')
;

Starten wir nun die Applikation neu, sehen wir die beiden Einträge in unserem DataGridView Objekt.

Nun passen wir noch die Spaltenbreite an. Dazu wählen wir das DataGridView Objekt aus und wechseln zu den Ereignissen. Bei DataSourceChanged erstellen wir ein neues Event mit Doppelklick in dem leeren Textfeld.

Diese Event wird jedesmal ausgelöst, wenn sich die Datenquelle des DataGridView Objektes ändert, also immer, wenn wir die Daten von der Datenbank abfragen.

Code-Snippet

 private void dgvCocktails_DataSourceChanged(object sender, EventArgs e)
{
//REFERENCE ZUR DATEGRIDVIEW
DataGridView dgv = sender as DataGridView;
foreach(DataGridViewColumn col in dgv.Columns)
{
//SPALTE FÜR DIE BESCHREIBUNG
if(col.Name.ToUpper() == "BESCHREIBUNG")
{
col.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
else
{
col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
}
}

Als erstes wird das sender Objekt in ein DataGridView Objekt umgewandelt. Dann gehen wir durch alle Spalten (foreach) und wenn die Spalte „Beschreibung“ heißt, setzen wir den AutoSizeMode auf Fill (Ausfüllen). Das hat zur Folge, dass die Spalte über den restlichen freien Bereich in der Ansicht aufgefüllt wird. Das macht vor allem für die Beschreibung Sinn, da hier der längere Text abgelegt ist. Das Ergebnis sieht wie folgt aus.

Abfrage mit individuellen SQL-Befehl

Nun möchten wir jedoch unsere Ergebnis-Tabelle ein wenig anpassen. Dazu ist aber ein andere SQL Befehl nötig. Um Daten auch direkt mit einem SQL-Befehl abfragen zu können, fügen wir eine neue Funktion ein.

Code-Snippet

 public DataTable DatenVonTabelleMitSQLBefehl(string SqlBefehl)
{
DataTable dt = new DataTable();
try
{
if (Connection.State != ConnectionState.Open)
Connection.Open();
String abfrage = SqlBefehl;
MySqlDataAdapter msda = new MySqlDataAdapter(abfrage, Connection);
msda.Fill(dt);
Connection.Close();
}
catch (MySqlException e)
{
MessageBox.Show(e.Message, "Datenbankfehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (Connection.State == ConnectionState.Open) Connection.Close();
}
return dt;
}

Diese Funktion ist ähnlich der bereits hinzugefügten Funktion, nur dass diese Funktion mit reinen SQL Befehlen funktioniert. Nun müssen wir nur noch die Funktion „DatenVonTabelle“ im „Form1_Shown“ Event ersetzten.

Wir ersetzen

dgvCocktails.DataSource = DatenVonTabelle("Cocktails");

mit

dgvCocktails.DataSource = DatenVonTabelleMitSQLBefehl("SELECT NAME AS 'Cocktail', BESCHREIBUNG AS 'Zubereitung' FROM Cocktails");

Das liefert uns folgendes Ergebnis.

Wie Sie sehen, verschwinden dann die Spalte ID, welche ja für den späteren Benutzer uninteressant ist. Des Weiteren können wir so auch direkt die Namen der Spalten beeinflussen.

0

0

Back To Top

Eingabemaske für Daten

Daten in die Datenbank einspielen

Die Ansicht ist soweit fertig. Nun wollen wir aber auch, dass Benutzer im Frontend neue Cocktails anlegen können. Dazu fügen wir zu unserem Projekt ein neues WindowsForm Element hinzu.

Neue Form

Rechtsklick auf Ihr Projekt => Hinzufügen => Windows Form…

Bennen Sie die Form „frmInput“ und bestätigen Sie Ihre Eingabe mit Hinzufügen.

Aussehen der Eingabemaske

Es öffnet sich anschließend der Ansicht-Designer für die neu hinzugefügte Form. Auch hier fügen wir zu erst ein TableLayoutPanel Objekt hinzu, welches unser Form eine Struktur gibt. Passt das Layout an, so dass es wie unten abgebildet aussieht.

Dann fügt folgende Objekte hinzu.

  • Labels für die Eingabeformen
  • Eine Textbox für den Cocktail (Name: tbCocktail) und die Beschreibung (tbBeschreibung) (bei letzteren setzt Ihr Multiline auf True)
  • Eine ComboBox (cbZutaten) und einen Button (btnNeueZutat) für die Zutat
  • Ein NumericUpAndDown Objekt (nudMenge) für die Menge und eine ComboBox (cbEinheiten) für die Einheit.
  • Einen Button für das Hinzufügen der Zutaten
  • Ein DataGridView Objekt für die Zutaten
  • Einen Button für Abbrechen (btnAbbrechen) und einen Button (btnCocktailAnlegen) für Anlegen

Funktionalität der Eingabemaske

Fügen Sie nun ein neues Event „Shown“ für die neue Eingabemaske hinzu. Hier werden wir nun die bereits angelegten Mengeneinheiten, sowie die Zutaten von der Datenbank laden und den jeweiligen ComboBox Objekten zuordnen. Dazu legen wir aber zunächst eine neue Funktion in unserer Hauptform an.



public List<string> holeDatenVonSpalte(string Tabelle, string Spalte, string Filter = "")
{
List<string> values = new List<string>();
try
{
if (Connection.State != ConnectionState.Open)
Connection.Open();
String abfrage = "SELECT " + Spalte + " FROM " + Tabelle + (Filter == "" ? String.Empty : " WHERE " + Filter);
MySqlDataAdapter msda = new MySqlDataAdapter(abfrage, Connection);
DataTable dt = new DataTable();
msda.Fill(dt);
Connection.Close();
foreach (DataRow row in dt.Rows)
{
if (!values.Contains(row[0].ToString()))
{
values.Add(row[0].ToString());
}
}
}
catch (MySqlException e)
{
MessageBox.Show(e.Message, "Datenbankfehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (Connection.State == ConnectionState.Open) Connection.Close();
}
return values;
}

Referenzen

Diese neue Funktion ermöglicht es uns, Daten aus einer bestimmten Spalte aus der Datenbank zu holen. Diese Daten können wir dann in unser ComboBox Element laden. Da die Funktion öfter gebraucht wird, platzieren wir diese in der Hauptform. Nun kann aber die Eingabemaske nicht ohne weiteres auf diese Funktion zugreifen. Dazu muss der Eingabemaske eine Referenz zu der Hauptform übergeben werden. Wir erweitern also unseren Konstruktor der Eingabemaske um einen Parameter, der als Typ den Namen der Hauptform entspricht.

 private frmMain main = null;
public frmInput(frmMain m)
{
InitializeComponent();
main = m;
}

Zutaten & Einheiten laden

Wir übergeben nun beim Erstellen der Eingabemaske eine Referenz auf die Hauptform (ref frmMain). Im Konstruktor wird diese Referenz dann einem leeren Objekt mit dem gleichen Datentyp zugewiesen, sodass diese auch in anderen Funktionen und Relationen der Eingabemaske verwendet werden kann. Ansonsten wäre das Objekt nur im Konstruktor zugreifbar. Wir wechseln nun wieder in unser „frmInput_Shown“ Event, welches wir zuvor generiert haben. Hier holen wir uns zuerst die Mengeneinheiten.

List<string> einheiten = main.holeDatenVonSpalte("Einheiten", "Einheit");

 

Danach fügen wir jedes Objekt der ComboBox cbEinheiten hinzu. Um das Ganze etwas dynamischer zu gestalten, fügen wir auch gleich eine AutoComplete Funktion hinzu. Dies erleichtert die spätere Eingabe bzw. Auswahl der Einheiten und Zutaten.

 AutoCompleteStringCollection sEinheiten = new AutoCompleteStringCollection();
//DATEN HINZUFÜGEN
foreach (string einheit in einheiten)
{
if (!sEinheiten.Contains(einheit))
sEinheiten.Add(einheit);
if (!cbEinheiten.Items.Contains(einheit))
cbEinheiten.Items.Add(einheit);
}
//COMBOBOX ANPASSEN
cbEinheiten.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
cbEinheiten.AutoCompleteSource = AutoCompleteSource.CustomSource;
cbEinheiten.AutoCompleteCustomSource = sEinheiten;

 

Zuerst erstellen wir eine neue, leere AutoCompleteStringCollection mit dem Namen „sEinheiten“ (s für engl. „source“). Dann fügen wir der Collection und der ComboBox die Einheiten aus der Datenbank hinzu. Das gleiche machen wir für die Zutaten.

 //ZUTATEN AUS DATENBANK LADEN
List<string> zutaten = main.holeDatenVonSpalte("Zutaten", "Zutat");
//AUTOVERVOLLSTÄNDIGUNG BEI DER EINGABE
AutoCompleteStringCollection sZutaten = new AutoCompleteStringCollection();
//DATEN HINZUFÜGEN
foreach (string zutat in zutaten)
{
if (!sZutaten.Contains(zutat))
sZutaten.Add(zutat);
if (!cbZutaten.Items.Contains(zutat))
cbZutaten.Items.Add(zutat);
}
//COMBOBOX ANPASSEN
cbZutaten.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
cbZutaten.AutoCompleteSource = AutoCompleteSource.CustomSource;
cbZutaten.AutoCompleteCustomSource = sZutaten;

Aufruf der Eingabemaske

Jetzt fehlt nur noch der Aufruf der Eingabemaske in der Hauptform. Dazu erstellen wir einen neuen Button in der Hauptform (obere, linke Spalte) und nennen diesen „btnNeu“ und geben ihm den Text „Neu“.

Durch einen Doppelklick auf den Button wird ein neues Event erstellt. Hier erstellen wir eine neue frmInput und übergeben hier die Referenz der Hauptform mit „this“ (this zeigt immer auf die aktuelle Form).

 private void btnNeu_Click(object sender, EventArgs e)
{
frmInput eingabe = new frmInput(this);
eingabe.ShowDialog();
}

1

0

Back To Top

Daten zurück in die Datenbank spielen

Neue Daten anlegen

Nun wollen wir aber auch neue Daten in der Datenbank ablegen können. Wir beginnen mit den Erstellen von neuen Zutaten. Um Daten in der Datenbank ablegen zu können, erstellen wir zuerst eine neue Funktion in der der Hauptform.

Funktion

 public bool DatenInTabelleSpeichern(string Tabelle, string[] Spalten, string[] Werte)
{
if (Spalten.Count() != Werte.Count())
throw new Exception("Die Anzahl der übergebenen Spalten stimmt nicht mit der Anzahl der übergebenen Werten überein:\n Spalten: "
+ Spalten.Count() + " / Werte:"
+ Werte.Count());
try
{
if (Connection.State != ConnectionState.Open)
Connection.Open();
StringBuilder abfrageString = new StringBuilder();
abfrageString.Append("INSERT INTO ");
abfrageString.Append(Tabelle + " (");
for (int i = 0; i < Spalten.Count(); i++)
{
abfrageString.Append("" + Spalten[i] + "");
if (i != Spalten.Count() - 1) abfrageString.Append(",");
}
abfrageString.Append(") ");
abfrageString.Append("VALUES (");
for (int i = 0; i < Werte.Count(); i++)
{
abfrageString.Append("'" + Werte[i] + "'");
if (i != Werte.Count() - 1) abfrageString.Append(",");
}
abfrageString.Append(")");
MySqlDataAdapter msda = new MySqlDataAdapter(abfrageString.ToString(), Connection);
msda.SelectCommand.ExecuteNonQuery();
Connection.Close();
return true;
}
catch (MySqlException e)
{
MessageBox.Show(e.Message, "Datenbankfehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (Connection.State == ConnectionState.Open) Connection.Close();
return false;
}
}

 

Diese Funktion ermöglicht es, Daten in den dazugehörigen Spalten abzulegen. Jetzt wechseln wir wieder zu unserer Form für die Eingabe. Durch einen Doppelklick auf den „Neue Zutaten“ Button, in der Eingabemaske, wird ein neues Event erstellt. Hier fragen wir zuerst ab, ob die Zutat nicht schon in der Datenbank existiert. Dazu legen wir noch eine weitere Funktion in der Hauptform an, welche uns sagt, ob der zu speichernde Wert schon existiert.

Prüfen ob Daten bereits existieren

 public bool PruefeObEintragExistiert(string Tabelle, string Spalte, string Wert)
{
DataTable dt = new DataTable();
try
{
if (Connection.State != ConnectionState.Open)
Connection.Open();
String abfrage = "SELECT * FROM " + Tabelle + " WHERE " + Spalte + " LIKE '" + Wert + "'";
MySqlDataAdapter msda = new MySqlDataAdapter(abfrage, Connection);
msda.Fill(dt);
Connection.Close();
return dt.Rows.Count > 0;
}
catch (MySqlException e)
{
MessageBox.Show(e.Message, "Datenbankfehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (Connection.State == ConnectionState.Open) Connection.Close();
return false;
}
}

 

Neue Zutat anlegen

Diese Funktion sucht den übergebenen Wert in der übergebenen Spalte. Liefert die Rückgabe kein Ergebnis, so ist das ein Anzeichen, dass der Wert noch nicht existiert. Die Datenbank würde aber auch automatisch merken, dass der zu speichernde Wert schon existiert. Das gibt aber eine eher kryptische Fehlermeldung. Deswegen prüfen wir das schon vorab und basteln uns eine eigene Fehlermeldung. Das ganze sieht dann wie folgt aus.

 private void btnNeueZutat_Click(object sender, EventArgs e)
{
//PRÜFE, OB DIE EINGABE LEER IST
if(cbZutaten.Text == "")
{
MessageBox.Show("Es wurde keine Zutat angegeben.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
//PRÜFE, OB DER ZU SPEICHERNDE WERT SCHON EXISTIERT
if(main.PruefeObEintragExistiert("Zutaten","Zutat",cbZutaten.Text))
{
MessageBox.Show("Die Zutat \"" + cbZutaten.Text + "\" existiert bereits in der Datenbank!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
//ZUTAT IN DER DATENBANK SPEICHERN
bool ergebnis = main.DatenInTabelleSpeichern("Zutaten", new string[] { "Zutat" }, new string[] { cbZutaten.Text });
if(ergebnis)
{
MessageBox.Show("Die Zutat \"" + cbZutaten.Text + "\" wurde erfolgreich in der Datenbank abgelegt", "Erfolgreich", MessageBoxButtons.OK, MessageBoxIcon.Information);
//ZUTAT ZUR COMBOBOX HINZUFÜGEN
cbZutaten.Items.Add(cbZutaten.Text);
cbZutaten.AutoCompleteCustomSource.Add(cbZutaten.Text);
}
}

 

Wenn die Eingabe nicht leer ist und der Eintrag noch nicht existiert, dann wird dieser in der Datenbank abgelegt. War das Ergebnis erfolgreich, dann wird die ComboBox und die AutoCompleteSource um den neuen Eintrag erweitert.

Neue Einheiten

Da wir für die Einheit einmal das Kürzel und einmal den Namen der Einheit in der Datenbank ablegen wollen, müssen wir unsere Eingabemaske anpassen. Wir fügen ein neuen Button „btnNeueEinheit“ und eine weitere TextBox „tbEinheitstext“ hinzu. Das Ganze sollte dann in etwa so aussehen.

Zunächst fügen wir ein neues Event für die ComboBox hinzu. Dazu einfach ein Doppelklick auf die ComboBox für die Einheitskürzel. Jedes Mal, wenn die Auswahl in der ComboBox geändert wird, holen wir uns zusätzlich den Einheitstext aus der Datenbank.

private void cbEinheiten_SelectedIndexChanged(object sender, EventArgs e)
{
//PRÜFE, OB DER ZU SPEICHERNDE WERT SCHON EXISTIERT
if (main.PruefeObEintragExistiert("Einheiten", "Einheit", cbEinheiten.Text))
{
List<string> einheitsnamen = main.holeDatenVonSpalte("Einheiten", "Einheitstext", "Einheit LIKE '" + cbEinheiten.Text + "'");
if (einheitsnamen.Count > 0)
{
tbEinheitstext.Text = einheitsnamen[0];
}
}
}

 

Starten wir nun die Applikation und wählen eine Einheit aus, dann wird der Text in der TextBox automatisch zu dem Einheitentext der entsprechenden Einheit gesetzt.

Soweit so gut. Nun sollte es aber auch möglich sein eine neue Einheit anzulegen. Dazu einen Doppelklick auf den Button „Neue Einheit“. Dann fügen wir folgenden Code zum Event des Buttons hinzu.

 private void btnNeueEinheit_Click(object sender, EventArgs e)
{
//PRÜFE, OB EINGABE LEER IST
if (cbEinheiten.Text == "" || tbEinheitstext.Text == "")
{
MessageBox.Show("Es wurde keine Einheit / kein Einheitstext angegeben.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
//PRÜFE, OB DER ZU SPEICHERNDE WERT SCHON EXISTIERT
if (main.PruefeObEintragExistiert("Einheiten", "Einheit", cbEinheiten.Text))
{
MessageBox.Show("Die Einheit \"" + cbEinheiten.Text + "\" existiert bereits in der Datenbank!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
//EINHEIT IN DER DATENBANK SPEICHERN
bool ergebnis = main.DatenInTabelleSpeichern("Einheiten", new string[] { "Einheit", "Einheitstext" }, new string[] { cbEinheiten.Text, tbEinheitstext.Text });
if (ergebnis)
{
MessageBox.Show("Die Einheit \"" + cbEinheiten.Text + "\" (" + tbEinheitstext.Text + ") wurde erfolgreich in der Datenbank abgelegt", "Erfolgreich", MessageBoxButtons.OK, MessageBoxIcon.Information);
//ZUTAT ZUR COMBOBOX HINZUFÜGEN
cbEinheiten.Items.Add(cbEinheiten.Text);
cbEinheiten.AutoCompleteCustomSource.Add(cbEinheiten.Text);
}
}

 

Hier wird zuerst geprüft, ob beide Textboxen befüllt sind. Dann wird geprüft, ob der Primärschlüssel, in diesem Fall das Einheitskürzel, bereits in der Datenbank existiert. Wenn nicht, dann wird die neue Einheit der Tabelle hinzugefügt und die ComboBox mit der neuen Einheit erweitert. Klicken wir nun den Button „Einheit hinzufügen“, wird die neue Einheit angelegt.

Neue Zutaten anlegen

Nun wollen wir aber auch Zutaten zu unserem Cocktail hinzufügen können. Da meistens mehrere Zutaten für einen Cocktail nötig sind, verwenden wir direkt eine Datentabelle (DataTable), welche wir mit Zeilen füllen.

Dazu deklarieren wir zuerst eine neue Datentabelle im Kopfbereich der Eingabemaske.

private DataTable zutaten = new DataTable();

Im Konstruktor der Form erstellen wir die benötigen Spalten für die Datentabelle und fügen diese der Tabelle hinzu. Des Weiteren wird die neue Tabelle als Datenquelle (DataSource) für das DataGridView Objekt verwendet.

private DataTable zutaten = new DataTable();
public frmInput(frmMain m)
{
InitializeComponent();
main = m;

//ERSTELLE SPALTEN
DataColumn zutat = new DataColumn("Zutat")
{
DataType = typeof(string),
};

DataColumn menge = new DataColumn("Menge")
{
DataType = typeof(int)
};
DataColumn einheit = new DataColumn("Einheit")
{
DataType = typeof(string)
};
zutaten.Columns.AddRange(new DataColumn[] { zutat, menge, einheit });
//SETZTE ZUTAT ALS PRIMÄRSCHLÜSSEL
zutaten.PrimaryKey = new DataColumn[] { zutat };
dgvZutaten.DataSource = zutaten;
}

Als nächstes erstellen wir mit einem Doppelklick auf den „Zutat hinzufügen“ Button das benötigte Event zum Hinzufügen neuer Zutaten zum Cocktail. Hier fügen wir folgenden Code hinzu.

 //PRÜFE, OB EINGABE LEER IST
if (cbZutaten.Text == "" || cbEinheiten.Text == "" || tbEinheitstext.Text == "")
{
MessageBox.Show("Es wurden nicht alle benötigten Informationen angegeben.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
//PRÜFE, OB MENGE GRÖSSER 0
else if(nudMenge.Value <= 0)
{
MessageBox.Show("Bitte geben Sie eine Menge für die Zutat an.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
DataRow neueZutat = zutaten.NewRow();
neueZutat["Zutat"] = cbZutaten.Text;
neueZutat["Menge"] = (int)nudMenge.Value;
neueZutat["Einheit"] = cbEinheiten.Text;
try
{
zutaten.Rows.Add(neueZutat);
}
catch(Exception exc)
{
MessageBox.Show(exc.Message, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}

 

Diese Funktion erstellt eine neue Datenzeile (DataRow) mit der Struktur der Datentabelle „zutaten„. So hat die Zeile die gleichen Spalten wie die „zutaten“ Tabelle. Nun weisen wir den einzelnen Spalten den Wert zu und versuchen diese Zeile in die Datentabelle einzufügen. Sofern noch keine Zeile mit der gleichen Zutat vorhanden ist, sollte das auch ohne Ausnahme funktionieren. Führen wir unser Tool nun aus, können wir bereits neue Zutaten anlegen und hinzufügen.

0

0

Back To Top

Was this article helpful?

Leave A Comment?

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.