Autor Beitrag
Talemantros
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Di 29.04.14 11:47 
Hallo,
ich möchte gern alle TextBoxen durchsuchen, ob der Benutzer sie ausgefüllt hat.
Wenn nicht, soll die TextBox markiert werden.

Nach einigen Verscuhen im Netz kam ich zu :

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
            foreach (Control C in grpDaten.Controls)
            {
                if (C.GetType() == typeof(TextBox))
                {
                    if (((TextBox)C).Text == string.Empty)
                    {
                        MsgAusgabe.ShowError("Bitte füllen Sie alle Felder aus!");
                        ((TextBox)C).Focus();
                        return;
                    }
                }
            }


Leider scheint er den Code nicht anständig zu durchlaufen.
Obwohl eine TextBox leer war läuft er nicht zur MessageBox

Danke
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Di 29.04.14 13:20 
Versuch mal so:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
foreach (var control in grpDaten.Controls)
{
    var textBox = control as TextBox;

    if (textBox != null && string.IsNullOrWhiteSpace(textBox.Text))
    {
        MsgAusgabe.ShowError("Bitte füllen Sie alle Felder aus!");
        textBox .Focus();
        break;
    }
}


Hab allgemein was umgebaut.

So ist es besser, den Typ entweder mit is oder as zu prüfen.
as castet die Variable in den angegebenen Typ, wenn das nicht geht, wird null zurück gegeben.
is gibt an, ob die Variable als der angegebene Typ darstellbar ist.

string.IsNullOrWhiteSpace(string) gibt an, ob der übergebene String null, leer ist, oder nur aus Leerzeichen besteht.
Das dürfte alleine schon den Fehler behoben haben, alles ANdere habe ich nur gemacht, weil ich es für besser halte.

Außerdem ist es vielleicht besser, wenn du alle betroffenen TextBoxen in einer Liste bereit hältst.
Je nachdem, wo die erstellt werden, kannst du die dann im Konstruktor oder direkt beim Erstell-Vorgang in dieser Liste ablegen und dann von dort aus ohne extra Überprüfung entsprechend prüfen.


Entsprechende Links:

is
as
string.IsNullOrWhiteSpace(string)

Ich hab dir hier jetzt alles mundgerecht auf bereitet, beachte aber auch, dass für ein Programmierer die Fähigkeit, diverse Suchfunktionen richtig zu verwenden, beinahe schon existenziell wichtig ist.
Keiner kann alles wissen, es ist daher notwendig, sich fehlende Informationen zu suchen und das Internet bietet dafür hervorragende Möglichkeiten.


Zuletzt bearbeitet von Palladin007 am Di 29.04.14 13:28, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 29.04.14 13:25 
Benutzt du DataBinding? Ich würde dich gerne weg von den UI Controls lotsen hin zu einer Modelklasse die ihre Konsistenz selbst prüfen könnte unabhängig von den Controls die letzlich benutzt werden um die Daten anzuzeigen.
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Di 29.04.14 17:10 
Hallo Palladin007,
vielen dann für den aufbereiteten Code, den werde ich gleich mal testen.
Hatte ja schon einiges gesucht und nachgelesen um den geposteten Code zu erreichen.

@Ralf
In diesem Fall ist es ein Forumlar, welches nur einige Daten abfragt.
Mir fehlt es da noch an Vorstellungskraft wie ich Databindigs verwenden könnte.
Wenn du die Zeit investieren möchtest würde ich mich gerne lotsen lassen.


Im konkreten Beispiel wollte ich ein paar Mitarbeiterdaten abfragen um einen Account auf der MySQL Datenbank anzulegen
Dazu hatte ich eine Modellklasse gemacht.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace Recycle.Logics
{
    public class Employee
    {
        private string vorname = string.Empty;
        private string nachname = string.Empty;
        private long secId = 0;
        private long gruppe = 0;

        public string Vorname { get; set; }
        public string Nachname { get; set; }
        public long SecId { get; set; }
        public long Gruppe { get; set; }

    }
}


Mein SpeichernButton sieht momentan so aus

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
        private void btnSpeichern_Click(object sender, EventArgs e)
        {
        private Employee newEmployee;

            if (cmbGruppe.SelectedIndex == -1)
            {
                MsgAusgabe.ShowError("Bitte wählen Sie eine Berechtigungsgruppe aus!");
                return;
            }

            foreach (Control C in grpDaten.Controls)
            {
                if (C.GetType() == typeof(TextBox))
                {
                    if (((TextBox)C).Text == string.Empty)
                    {
                        MsgAusgabe.ShowError("Bitte füllen Sie alle Felder aus!");
                        ((TextBox)C).Focus();
                        return;
                    }
                }
            }

            newEmployee.Vorname = txtVorname.Text;
            newEmployee.Nachname = txtNachname.Text;
            newEmployee.SecID = Convert.ToInt64(txtSecId.Text);
            newEmployee.Gruppe = Convert.ToInt64(cmbGruppe.SelectedValue);

            if (EmployeeMethods.CheckEmployee(newEmployee) == 1)
            {
                MsgAusgabe.ShowError("Dieser Mitarbeiter ist bereits im System angelegt wurden!");
                return;
            }

            try
            {
                EmployeeMethods.SetEmployee(newEmployee);
                MySqlHistorie.SetHistorie(DbInfo.GetMySqlConnStr(), "Mitarbeiterverwaltung""Mitarbeiter", newEmployee.Nachname + "_" + newEmployee.Vorname + " angelegt""Ich");
                MsgAusgabe.ShowInformation("Mitarbeiter erfolgreich gespeichert!");
                ClearAttributes();
            }
            catch (Exception ex)
            {
                MsgAusgabe.ShowError(ex.Message);
                throw;
            }
        }


@Palladin007
Also der Code wird auch ignoriert und prüft die TextBoxen nicht durch. Denke ich habe irgendwo nen Dreher :-(
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4796
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 29.04.14 17:18 
Hallo Talemantros,

liegen die Textboxen direkt in der GroupBox 'grpDaten'? Oder doch in weiteren Subcontainern, denn dann müßtest du rekursiv diese Container durchsuchen.

Aber wie Ralf schon schrieb, schöner wäre ein Validierungsansatz mittels DataBinding. Unschön an deinem Code bisher ist z.B. die Verwendung der Convert.ToInt64-Methode, da diese eine Exception wirft, wenn keine Zahl in der TextBox drin steht.
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Di 29.04.14 19:00 
Hi Th69,
also von mir wurde kein anderer SubContainer angelegt! Wie könnte ich dies sehen?

Die txtsecid kann nicht leer sein, da sie beim Load des UserControls per Zufallsgenerator gefüllt wird. Wäre sonst die tryParse besser?

Würde mir das gern ansehen wie man mit der Validierung mittels Databindung arbeitet.
Das wär für viele weitere Module die ich noch bauen will sehr hilfreich.

In der Zwischenzeit versuche ich gerade dein Beispielprojekt besser zu verstehen.

Danke
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Di 29.04.14 20:17 
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
            if (cmbGruppe.SelectedIndex == -1)
            {
                MsgAusgabe.ShowError("Bitte wählen Sie eine Berechtigungsgruppe aus!");
                return;
            }


Kann es sein, dass die Methode hier raus springt?
Aus dem Grund setze ich returns nach Möglichkeit nur am Ende, damit ich kein return irgendwo übersehe und sicher bin, dass die Methode garantiert und in jedem Fall bis zum Ende durch läuft.
Das kannst du aber auch testen, indem du einfach mal einen Breakpoint an den Anfang der foreach-Schleife setzt und dann mit F10 Schritt für Schritt die einzelnen Durchläufe mit verfolgst und dir anschaust, was dein Programm im Detail tut.

Dazu kommt natürlich noch das, was Th69 gesagt hat.

Neben dem DataBinding-Ansatz (um es schneller und ohne große Änderungen zu lösen), kannst du doch einfach mal meinen Tipp von meinem letzten Post ausprobieren, nämlich indem du die betroffenen Controls in eine Liste legst. Dann musst du nicht auf den Typ prüfen und musst nicht rekusiv alle Controls ab suchen. Die betroffenen Controls kennst du ja und kannst sie im Konstruktor in die Liste legen.

Dennoch wäre DataBinding der saubere Weg.


Zum Verständnis, wie und wo man das verwendet:
Es gibt ein Pattern namens MVVM (Model-View-ViewModel). Das wurde (wenn ich mich nicht irre) besonders im Hinblick auf WPF entworfen, kann aber auch bei WindowsForms angewendet werden.
Einfach zusammen gefasst:

Model:
Das reine Daten-Objekt. Es enthält die Daten aus der Datenbank. Dort werden die abgerufenen Daten rein gelegt und von dort werden neue Daten in die Datenbank gespeichert.
Hier liegt bis auf die reine Validierungs-Logik keine Programm-Logik.

View:
Das ist eine Oberfläche, sie macht nichts außer anzeigen und Daten via DataBinding mit dem ViewModel auszutauschen.

ViewModel:
Wie der Name schon sagt, ist es eine Art Mischung aus View und Model.
Konkret betrachtet ist ein ViewModel das Objekt, das die Logik für die View bereit hält.
Es bekommt seine Daten von dem Model und bereitet sie so auf, dass die View vollständig ohne weitere Logik Diese korrekt anzeigen kann.
Das DataBinding ist dabei die Schnittstelle zwischen View und ViewModel. Die View braucht Daten und sucht sie über diese Schnittstelle bei dem ViewModel und das ViewModel bekommt neu eingegebene Daten über diese Schnittstelle von der View.

Ob das Konzept so sauber mit Windows Forms umsetzbar ist, weiß ich nicht, bei WPF ist es aber möglich, eine View komplett ohne C# zu bauen und ohne irgendeinen Teil des Programms zu kennen. Die einzige Ausnahme hier bildet das ViewModel.

Der Vorteil ist, dass die View unabhängig vom Programm von z.B. einem Designer, der nur geringe C#-Kenntnisse braucht, entwickelt werden kann.
Außerdem kannst du Validierung von eingegebenen Daten im ViewModel machen, da hast du nicht das ganze Chaos drum herum, was die View dar stellt und das ist bei Forms ja sowieso recht umfangreich.



Ich schau grad nach einem Beispiel, da ich selber mich nie wirklich mit Windows Forms anfreunden konnte und DataBinding noch nie dort genutzt habe :D
Ansonsten google du doch mal, auf msdn gibts sowas wie ein riesiges Tutorial.

PS: Schau hier mal. Scheint ganz gut zu sein.
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Di 29.04.14 20:38 
Danke für die ausführliche Antwort.
Mir ist noch nicht ganz klar wie man das baut, werde aber morgen versuchen mir das zu Gemüte zu führen, damit ich direkt so weiter arbeiten kann.

Ich bin gespannt wie weit ich komme.

Gruß

EDIT: Also habe mir das schon einige Male jetzt angeschaut finde aber nicht den Dreh wie ich die Modellklasse bauen müsste damit sie sich selber validiert.
Würde mich über einige Hinweise oder Code freuen.

Würde dann morgen gleich das erste Form dieser Art umbauen und hätte einen guten Start in die nächsten kommenden Module

Danke
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 29.04.14 22:06 
Palladin007's Link beschreibt das Verfahren aus der Sicht des Jahres 2002 (ungefähr). Das würde immer noch gehen aber es macht so keiner mehr.
Ich versuche mal frei die Steps zu beschreiben die nötig sind.

a.) Wirf im Designer eine BindingSource auf die Form (und benenn die vernünftig).
b.) In den Eigenschaften der BindingSource suchst du die DataSource Property raus und öffnest in dessen DropDownList den Punkt 'Add Project DataSource aus'.

AddDataSource

c.) Im folgenden Dialog wählst du dann deine Employee Klasse in den angebotenen Klassen aus (wenn die fehlt nochmal kompilieren).

AddClass

c.) Jetzt gehst du auf irgendeine deiner TextBoxen öffnest die ~Pseudo~ Property (DataBindings) und siehst eine Liste der üblichen bindbaren Properties dieses Controls.
Unter anderem sollte dir die Text Property angeboten werden. In dessen DropDown wählst du die gewünschte Property deiner Klasse über die BindingSource aus die du zum binden verwendet hast.

BindToTextBox

d.) Wenn das für alle Controls erledigt ist kannst du nun über die DataSource Property der BindingSource eine Employee Instanz zuweisen und am Ende wieder entnehmen.
Es sollte kein direkter auf irgendein UI Control mehr notwendig sein. Die Daten der Controls kommen aus der Klasse und landen beim verlassen einen Controls direkt wieder in der Klasse.
Auch die Convertierung nach long passiert automatisch (durch das Databinding wird verhindert das du Unsinn eingeben kannst).

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
// Zuweisung am Anfang, die Employee Instanz kann auch sonst woher kommen die muss nicht neu angelegt sein
bsEmployee.DataSource = new Employee();

// speichern, dein Code simplifiziert und um Vollständigkeitstest ergänzt
Employee newEmployee = bsEmployee.DataSource as Employee;

if (!newEmployee.IsValid)
    MsgAusgabe.ShowError("Bitte füllen Sie alle Felder aus!");
else if (EmployeeMethods.CheckEmployee(newEmployee) == 1)
    MsgAusgabe.ShowError("Dieser Mitarbeiter ist bereits im System angelegt wurden!");
else
    EmployeeMethods.SetEmployee(newEmployee);



Deine Employee Klasse leicht angepasst. Deine privaten Felder sind unnütz die automatischen Properties benutzen die nicht. Und die Longs habe ich nullable gemacht sonst haben die ja schon initial den Wert 0 und eben nicht keinen. Zusatzlich die IsValid Methode mit dem Vollständigkeitstest. Kannst du auch Alternativ in deiner EmployeeMethods Klasse unterbringen.


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
public class Employee
{
    public string Vorname { get; set; }
    public string Nachname { get; set; }
    public long? SecId { get; set; }
    public long? Gruppe { get; set; }

    public bool IsValid
    {
        get
        {
            return !string.IsNullOrWhiteSpace(Vorname) &&
                    !string.IsNullOrWhiteSpace(Nachname) &&
                    SecId.HasValue &&
                    Gruppe.HasValue;
        }
    }
}
Einloggen, um Attachments anzusehen!
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Mi 30.04.14 18:32 
Hallo Ralf,
leider komme ich erst jetzt wieder ein wenig zum lernen/basteln.
Ich danke dir für die Anleitung. Habe dies so umgesetzt, aber leider läuft es noch nicht.

Code der Modellklasse
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace Recycle.Logics
{
    public class Employee
    {
        public string Vorname { get; set; }
        public string Nachname { get; set; }
        public long? SecId { get; set; }
        public long? Gruppe { get; set; }

        public bool IsValid
        {
            get
            {
                return !string.IsNullOrWhiteSpace(Vorname) &&
                        !string.IsNullOrWhiteSpace(Nachname) &&
                        SecId.HasValue &&
                        Gruppe.HasValue;
            }
        }
    }
}


Code hinter dem UserControl
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
        private void MitarbeiterNeuUserControl_Load(object sender, EventArgs e)
        {
            txtVorname.Focus();

            cmbGruppe.DataSource = PermissionMethods.GetGroups();
            cmbGruppe.DisplayMember = "name";
            cmbGruppe.ValueMember = "berechtigunggruppeid";
            cmbGruppe.SelectedIndex = -1;

            bsEmployee.DataSource = new Employee();
        }

        private void btnSpeichern_Click(object sender, EventArgs e)
        {
            Employee newEmployee = bsEmployee.DataSource as Employee;

            if (!newEmployee.IsValid)
                MsgAusgabe.ShowError("Bitte füllen Sie alle Felder aus!");
            else if (EmployeeMethods.CheckEmployee(newEmployee) == 1)
                MsgAusgabe.ShowError("Dieser Mitarbeiter ist bereits im System angelegt wurden!");
            else
                EmployeeMethods.SetEmployee(newEmployee);
        }


Er bemängelt immer, dass nicht alle Felder ausgefüllt wurden.
Nach einigem testen denke ich es liegt es daran, dass er keinen Wert aus der Combobox bekommt, die mit der Property Gruppe als Long definiert ist.

Ich lade die Daten dort aus einer Methode, die einen DataTable zurück gibt (siehe load)
Und irgendwie scheint er da Schwierigkeiten zu haben. In der Datenbank möchte ich nur eine Zahl speichern die ein Fremdschlüssel zu einer anderen Tabelle darstellt.
Daher ist Gruppe ein Long und nicht string.

Könntest du mir da weiterhelfen?

Gruß
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 01.05.14 10:31 
Bei einer ComboBox solltest du eher SelectedItem binden und nicht Text Property so wie ich das bei TextBoxen beschrieben habe.
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Do 01.05.14 14:27 
Hi,
ich hatte jetzt die Property an SelecedItem gebunden.
Leider wird der Code dann gar nicht mehr ausgeführt, es kommt aber auch keine Fehlermeldung.
Wenn ich das an SelecedValue binde geht es und er schreibt auch den LongWert statt des Strings in die Datenbank

Soweit so gut.

Eine Frage hätte ich noch!
Wäre es so möglich, den Focus auf eine der leeren TextBoxen zu setzen?

Danke

Jetzt muss ich noch Probleme mit der per Zufallszahl generierten SecID lösen, die irgendwie Fehler produziert. Aber es geht voran :-)
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 01.05.14 16:22 
Zitat:
Wäre es so möglich, den Focus auf eine der leeren TextBoxen zu setzen?


Dafür müßtest du tatsächlich näher an die UI ran und direkt die Controls prüfen. Man könnte zwar irgendwas an die Modelklasse basteln so das sie die betroffene Property zurückmeldet und der Aufrufer daraufhin das passende Control focusiert. Würde ich aber nicht tun da das kaum generisch lösbar ist und ich eine Trennung von sauberer Modelvalidierung (du könntest auf die Idee kommen Employees ohne UI anzulegen und die jetzige Validierung funktioniert auch dann) und UI Verhalten vorziehe. Wenn ein solches Verhalten wichtig ist würde ich das mit einem ErrorProvider machen der beim Validieren die passende Fehlermeldung generiert und den Focus passend setzt unabhängig von der Validierung in der Modelklasse.
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Do 01.05.14 16:36 
Super vielen Dank
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Do 01.05.14 19:05 
Wie wäre es mit einer Art TrySet-Methode?

Die Methode bekommt den Namen der Eigenschaft und den Wert. Als Ergebnis gibt es entweder die Info, dass es geklappt hat, oder eine Fehlermeldung.
Die Info kann dann ja eine eigene Klasse namens ErrorInfo sein und wenn es keinen Fehler gibt, ist der Rückgabewert null.

Wenn es eine Möglichkeit gibt, über das Binding an den Namen der Eigenschaft zu kommen, an die ein Control gebunden ist, dann muss der Name auch nicht mehr so klar in den Code geschrieben werden.

Oder eine entsprechende Methode für jede Eigenschaft einzeln.


In der View läufst du dann jedes Control, das relevant ist, durch (ich würde immer noch die Liste nehmen), schickst den Wert an die entsprechende Try-Methode und wenn das Ergebnis nicht null ist, wird der ErrorProvider mit dem Control und der Fehlermeldung in dem Error-Info-Objekt gefüttert.