/// <summary>
        /// Gets all existing Kunden from the Database and adds them to the existingKundenComboBox
        /// </summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The event args</param>
        /// <param name="type">Is false in case of Kunde, is true in case of Kontakt</param>
        public static void BindFromExistingKundenToComboBox(object sender, EventArgs e, bool type = false)
        {
            // check sender for null
            if (sender == null)
            {
                return;
            }

            List<KundeKontaktTable> results;

            // add empty element to make empty choices possible
            List<string> listItems = new List<string>();
            listItems.Add("");

            KundenKontakteLoader loader = new KundenKontakteLoader();

            // Create empty Kunden object with type "false"
            KundeKontaktTable k = new KundeKontaktTable();
            k.Vorname = string.Empty;
            k.NachnameFirmenname = string.Empty;
            k.Type = type; // only get Kunden or Kontakte

            // Load all existing Kunden to object result list
            results = loader.LoadKundenKontakte(k, null);

            // if there are results, add them to string result list
            if (results.Count != 0)
            {
                foreach (KundeKontaktTable kunde in results)
                {
                    string entry = kunde.ID + ": " + kunde.Vorname + " - " + kunde.NachnameFirmenname;
                    listItems.Add(entry);
                }
            }

            // set data source
            (sender as ComboBox).DataSource = listItems;
        }
        /// <summary>
        /// Reads values of concerning fields and asks business layer to create a new Angebot with the provided parameters
        /// </summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The event params</param>
        private void CreateNewAngebot(object sender, EventArgs e)
        {
            // reset error/success labels
            this.createAngebotMsgLabel.Hide();
            this.createAngebotMsgLabel.Text = string.Empty;

            // existing or newly to-be-created
            bool createKunde = false;
            string kundenID = null;

            // Table for the Kontakt
            KundeKontaktTable k = new KundeKontaktTable();

            // new Kunde
            if (this.angebotErstellenSubTab.SelectedTab == this.angebotErstellenSubTab.TabPages[0])
            {
                createKunde = true;
            }
            // existing Kunde
            else
            {
                // no Kunde chosen or first element chosen (which is empty) -> show error label
                if (this.createAngebotExistingKundeComboBox.SelectedIndex <= 0)
                {
                    this.createAngebotMsgLabel.Text = "Error: kein Kunde ausgewählt";
                    this.createAngebotMsgLabel.ForeColor = Color.Red;
                    this.createAngebotMsgLabel.Show();
                    return; // skip rest of function
                }
                // Kunde chosen - get ID out of ComboBox
                else
                {
                    kundenID = this.createAngebotExistingKundeComboBox.SelectedItem.ToString();
                    kundenID = kundenID.Substring(0, kundenID.IndexOf(':'));

                    IRule posint = new PositiveIntValidator();
                    k.ID = DataBindingFramework.BindFromInt(kundenID, "KundenID", this.createAngebotMsgLabel, false, posint);

                    // Check for errors while databinding
                    if (posint.HasErrors)
                    {
                        this.logger.Log(Logger.Level.Error, k.ID + " is an invalid Kunden ID");
                        return;
                    }

                    // get Kunde table out of Database
                    KundenKontakteLoader loader = new KundenKontakteLoader();
                    List<KundeKontaktTable> results = loader.LoadKundenKontakte(k.ID, false);

                    // there must be exactly one result, for ID is unique!
                    if (results.Count != 1)
                    {
                        this.logger.Log(Logger.Level.Error, "More than one Kunde returned - impossible, because ID is unique!");
                        this.createAngebotMsgLabel.Text = "Error: Datenbank inkonsistent!";
                        this.createAngebotMsgLabel.Visible = true;
                        return; // skip rest of function
                    }

                    // everything went fine
                    k = results[0];
                }
            }

            // Create new Kunde, if requested
            if (createKunde)
            {
                // define Rules
                IRule lhv = new LettersHyphenValidator();
                IRule lnhsv = new LettersNumbersHyphenSpaceValidator();
                IRule slv = new StringLength150Validator();

                // validate data
                k.Vorname = DataBindingFramework.BindFromString(this.createAngebotNewKundeVnTextBox.Text, "Vorname", this.createAngebotMsgLabel, true, lhv, slv);
                k.NachnameFirmenname = DataBindingFramework.BindFromString(this.createAngebotNewKundeNnTextBox.Text, "Nachname", this.createAngebotMsgLabel, false, lnhsv, slv);
                k.Type = false; // Kunde

                if (lhv.HasErrors || lnhsv.HasErrors || slv.HasErrors)
                {
                    this.logger.Log(Logger.Level.Error, "Invalid signs within create Angebot / create Kunde");
                    return;
                }

                KundenKontakteSaver saver = new KundenKontakteSaver();

                try
                {
                    k.ID = saver.SaveNewKundeKontakt(k, this.createAngebotMsgLabel);
                }
                catch (InvalidInputException ex)
                {
                    this.logger.Log(Logger.Level.Error, ex.Message + ex.StackTrace);
                    this.createAngebotMsgLabel.Text = "Error: Kundenfelder ungültig!";
                    this.createAngebotMsgLabel.Visible = true;
                    return;
                }
                catch (SQLiteException ex)
                {
                    this.logger.Log(Logger.Level.Error, ex.Message + ex.StackTrace);
                    this.createAngebotMsgLabel.Text = "Error: Datenbankproblem!";
                    this.createAngebotMsgLabel.Visible = true;
                    return;
                }

                this.createAngebotMsgLabel.Text = "Kunde wurde gespeichert.";
            }

            // Create Angebot business object
            this.logger.Log(Logger.Level.Info, "Start creating new Angebot...");

            // define Rules
            IRule pdv2 = new PositiveDoubleValidator();
            IRule pcv2 = new PercentValidator();
            IRule dv2 = new DateValidator();
            IRule lnhsv2 = new LettersNumbersHyphenSpaceValidator();
            IRule slv2 = new StringLength150Validator();
            IRule piv2 = new PositiveIntValidator();

            AngebotTable angebot = new AngebotTable();
            angebot.Angebotssumme = DataBindingFramework.BindFromDouble(this.createAngebotAngebotssummeTextBox.Text, "Angebotssumme", this.createAngebotMsgLabel, false, pdv2);
            angebot.Umsetzungschance = DataBindingFramework.BindFromInt(this.createAngebotUmsetzungswahrscheinlichkeitTextBox.Text, "Umsetzungschance", this.createAngebotMsgLabel, false, pcv2);
            angebot.Angebotsdauer = DataBindingFramework.BindFromString(this.angebotValidUntilDateTimePicker.Value.ToShortDateString(), "GültigBis", this.createAngebotMsgLabel, false, dv2);
            angebot.Beschreibung = DataBindingFramework.BindFromString(this.createAngebotDescriptionTextBox.Text, "Beschreibung", this.createAngebotMsgLabel, false, lnhsv2, slv2);
            angebot.KundenID = DataBindingFramework.BindFromInt(k.ID.ToString(), "kundenID", this.createAngebotMsgLabel, false, piv2);
            angebot.Erstellungsdatum = DateTime.Now.ToShortDateString();

            // in case of errors in Databinding
            if (createAngebotMsgLabel.Visible)
            {
                this.logger.Log(Logger.Level.Error, "No angebot has been saved because of invalid inputs.");
                //createAngebotMsgLabel.ForeColor = Color.Red;
                //createAngebotMsgLabel.Show();
                return;
            }

            // send Angebot object to database
            try
            {
                AngebotManager manager = new AngebotManager();
                manager.Create(angebot, createAngebotMsgLabel);
            }
            catch (InvalidInputException ex)
            {
                this.logger.Log(Logger.Level.Error, ex.Message + ex.StackTrace);
                this.createAngebotMsgLabel.Text += "\nError: " + ex.Message;
                this.createAngebotMsgLabel.Show();
            }
            catch (SQLiteException ex)
            {
                this.logger.Log(Logger.Level.Error, ex.Message + ex.StackTrace);
                this.createAngebotMsgLabel.Text += "\nError: " + ex.Message;
                this.createAngebotMsgLabel.Show();
            }

            // show success message, if no error has been thrown
            if (!createAngebotMsgLabel.Visible)
            {
                this.createAngebotMsgLabel.Text += "\nAngebot wurde gespeichert.";
                this.createAngebotMsgLabel.ForeColor = Color.Green;
                this.createAngebotMsgLabel.Show();
            }
        }
        /// <summary>
        /// Gets Kunden or Kontakte out of the database (over the business layer, which checks for valid input)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SearchKundenOrKontakte(object sender, EventArgs e)
        {
            // hide error message
            this.HideMsgLabels();

            // define rules
            IRule lhv = new LettersHyphenValidator();
            IRule lnhsv = new LettersNumbersHyphenSpaceValidator();
            IRule slv = new StringLength150Validator();

            KundeKontaktTable k = new KundeKontaktTable();
            k.Vorname = DataBindingFramework.BindFromString(this.searchKundeVornameTextBlock.Text, "Vorname", this.searchKundeMsgLabel, true, lhv, slv);
            k.NachnameFirmenname = DataBindingFramework.BindFromString(this.searchKundeNachnameTextBlock.Text, "Nachname", this.searchKundeMsgLabel, true, lnhsv, slv);
            k.Type = this.searchKontaktRadioButton.Checked; // False...Kunde, true...Kontakt

            KundenKontakteLoader loader = new KundenKontakteLoader();

            // only if binding had no errors
            if (!this.searchKundeMsgLabel.Visible)
            {
                List<KundeKontaktTable> results;

                results = loader.LoadKundenKontakte(k, this.searchKundeMsgLabel);
                this.kundenSuchenBindingSource.DataSource = results;
            }

            this.BindToKundenSearchLabels(this.kundenSearchDataGridView, null);
        }