Laden...

PictureBox - Ungültiger Parameter [und warum File.Exists gefährlich und meistens sinnlos ist]

Erstellt von tööö vor 14 Jahren Letzter Beitrag vor 14 Jahren 4.512 Views
T
tööö Themenstarter:in
92 Beiträge seit 2006
vor 14 Jahren
PictureBox - Ungültiger Parameter [und warum File.Exists gefährlich und meistens sinnlos ist]

Hallo,

wie ich im Internet gesehen habe, haben einige diesen Fehler, aber eine Lösung habe ich leider nicht für mich gefunden.

Es geht um folgende Funktion


private void MSFelderLeeren()
        {
            cbx_MSMannschaft.Text = "";
            tbx_MSMannschaft.Text = "";
            lbl_MSDateiname.Text = "Unknown.jpg";
            pic_MSWappen.Image = new Bitmap("Wappen\\" + lbl_MSDateiname.Text);
            tbx_MSMannschaft.Focus();
        }

An sich funktioniert die Funktion wunderbar. Sie wird zum Beispiel aufgerufen, wenn das entsprechende Formular geöffnet wird. Dann wird auch das Bild "Unknown.jpg" richtig angezeigt.

Dann wird die Funktion auch noch aufgerufen, wenn ich einen Datensatz in meine Access-DB speicher, sodass nach dem Speichern wieder alle Felder leer sind. Aber dann bringt er komischerweise in der Zeile:

            pic_MSWappen.Image = new Bitmap("Wappen\\" + lbl_MSDateiname.Text);

den Fehler "Ungültiger Parameter". Ich weiß leider wirklich nicht mehr weiter. Bild ist da und wie gesagt, durchgelaufen ohne Fehler ist die Funktion ja auch schon.

Hier auch noch die Speichern-Funktion, wo die oben genannte Funktion auch aufgerufen wird, aber es eben zu diesem Fehler kommt.


private void btn_MSSpeichern_Click(object sender, EventArgs e)
        {
            // Prüfen, ob es die Mannschaft schon gibt
            this.sql = "SELECT * FROM T_Mannschaften WHERE MMannschaft = " +
                            "'" + cbx_MSMannschaft.SelectedItem.ToString() + "'";
            this.daten = this.conn.GibDataset(this.sql, "T_Mannschaften");

            // Mannschaft ist schon vorhanden
            if (this.daten.Tables[0].Rows.Count > 0)
            {
                // Soll die Mannschaft bearbeitet werden?
                if (MessageBox.Show("Die Mannschaft existiert schon.\nSoll die vorhandene Mannschaft bearbeitet werden?",
                                    "Mannschaft speichern",
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    this.sql = "UPDATE T_Mannschaften SET" +
                                " MMannschaft = '" + tbx_MSMannschaft.Text + "', " +
                                " MBild = '" + lbl_MSDateiname.Text + "'" +
                                " WHERE MMannschaft = " +
                                "'" + cbx_MSMannschaft.SelectedItem.ToString() + "'";
                    this.conn.GibDataset(this.sql, "T_Mannschaften");

                    // Alle Mannschaften erneut laden
                    MSLadeMannschaften();
                    MSFelderLeeren();
                    MSLadeMannschaften();
                }
            }
            else // Mannschaft ist neu
            {
                this.sql = "INSERT INTO T_Mannschaften VALUES (" +
                            "'" + tbx_MSMannschaft.Text + "'" + ", " +
                            "'" + lbl_MSDateiname.Text + "'" + ")";

                this.conn.GibDataset(this.sql, "T_Mannschaften");

                // Alle Mannschaften erneut laden
                MSLadeMannschaften();
                MSFelderLeeren();
                MSLadeMannschaften();
            }
        }

Ich hoffe, ihr könnt mir da weiterhelfen:

Liebe Grüße
tööö

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo tööö,

vermutlich wird irgendwo Environment.CurrentDirectory verstellt.

herbivore

T
tööö Themenstarter:in
92 Beiträge seit 2006
vor 14 Jahren

Hallo herbivore,

ich habe mir jetzt mal vor dem Befehl Environment.CurrentDirectory ausgeben lassen und tatsächlich, daran liegts. Super 😉

Nun aber folgende Frage. Direkt verstell ich den CurrentDirectory nicht. Das macht er irgendwie selbst nur, wenn er hier reinspringt in der Speichern-Funktion:


if (MessageBox.Show("Die Mannschaft existiert schon.\nSoll die vorhandene Mannschaft bearbeitet werden?",
                                    "Mannschaft speichern",
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    this.sql = "UPDATE T_Mannschaften SET" +
                                " MMannschaft = '" + tbx_MSMannschaft.Text + "', " +
                                " MBild = '" + lbl_MSDateiname.Text + "'" +
                                " WHERE MMannschaft = " +
                                "'" + cbx_MSMannschaft.SelectedItem.ToString() + "'";
                    this.conn.GibDataset(this.sql, "T_Mannschaften");

                    // Alle Mannschaften erneut laden
                    MSLadeMannschaften();
                    MSFelderLeeren();
                    MSLadeMannschaften();
                }

Aber wie kann ich den CurrentDirectory wieder zurücksetzen? Ich will das ja dynamisch halten...und nicht direkt ein Pfad in den Quellcode schreiben.

Liebe Grüße
tööö

T
1 Beiträge seit 2010
vor 14 Jahren

ich würde mich nicht auf eine bestimmte datei im filesystem verlassen und daher würde ich in diesem fall das bild selber zeichnen :


			Bitmap bitmap = new Bitmap(this.pictureBox1.ClientSize.Width, this.pictureBox1.ClientSize.Height);
			Graphics graphics = Graphics.FromImage(bitmap);

			graphics.FillRectangle(new SolidBrush(Color.WhiteSmoke), 0, 0, bitmap.Width, bitmap.Height);
			graphics.DrawString("Unknown", new Font("Times New Roman", 20), Brushes.LightSteelBlue, 10f, 10f);

			this.pictureBox1.Image = bitmap;


für das standard bild! die anderen bilder gehören in jedem Fall in die Datenbank!

LG
Mario

T
tööö Themenstarter:in
92 Beiträge seit 2006
vor 14 Jahren

Ahh, so wie ich sehe, verstellt mein OpenFileDialog den CurrentDirectory. Aber wie bekomm ich den zurückgestellt ohne den Pfad direkt in den Quellcode zu schreiben? 😕


if (ofd_MSWappenOeffnen.ShowDialog() == DialogResult.OK)
            {
                // Eine Datei wurde ausgewählt
                // Bild in der PictureBox anzeigen
                Bitmap wappen = new Bitmap(ofd_MSWappenOeffnen.FileName);
                pic_MSWappen.Image = wappen;
                lbl_MSDateiname.Text = Path.GetFileName(ofd_MSWappenOeffnen.FileName);
            }

Liebe Grüße
tööö

Gelöschter Account
vor 14 Jahren

zurückstellen musst/sollst du auch nicht. am besten du verwendest eine alternative aus: [FAQ] Pfad zur eigenen Anwendung (EXE) ermitteln

T
tööö Themenstarter:in
92 Beiträge seit 2006
vor 14 Jahren

Ich musste einfach die Eigenschaft "RestoreDirectory" vom OpenFileDialog auf True setzen. Nun klappt es wunderbar 😃

Danke für die schnelle Hilfe!

Liebe Grüße
tööö

M
27 Beiträge seit 2010
vor 14 Jahren

Hallo

ich würde nie auf eine Datei zugreifen, ohne vorrher zu testen ob diese Existiert.

Aber um das Programverzeichnis herraus zufinden kannst du

Application.StartupPath;

benutzen

T
tööö Themenstarter:in
92 Beiträge seit 2006
vor 14 Jahren

Ja, so habe ich das nun auch gemacht.
Und eine Prüfung, ob das Bild existiert, habe ich nun auch eingebaut.

Danke für die Tipps 😃

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo MotS,

im konkreten Fall wird File.Exists vermutlich recht zuverlässige Ergebnisse liefern. Im allgemeinen und auch hier kann man sich trotzdem das File.Exists sparen. Denn in Mulittasking-Systemen ist das Ergebnis des Tests sofort nach dem Test schon wieder unsicher oder eben sogar hinfällig. Natürlich ist die Wahrscheinlichkeit gering, dass die Datei genau zwischen Test und Zugriff entfernt oder umbenannt wird, aber sie kann ja auch von einem anderen Prozess exklusiv geöffnet worden sein und sich selbst nicht öffnen lassen, obwohl sie existiert.

Langer Rede, kurzer Sinn. Man sollte File.Exists vergessen und stattdessen um den Zugriff auf die Datei ein try/catch setzen.

Das gilt für alle Arten von Tests, die man vorher versucht, z.B. auf das ReadOnly-Flag oder die Zugriffsrechte. Für alles gilt, das Ergebnis des Tests kann unmittelbar nach dem Test schon nicht mehr zutreffend sein.

Wer sagt, dass eine solche Änderung ja sehr unwahrscheinlich ist, sollte sich bewusst sein, dass genau das bedeutet, dass wenn der Fehler doch auftritt, er natürlich entsprechend schwer zu finden ist. Und man möchte ja Software schreiben, die nicht nur meistens, sondern möglichst immer korrekt funktioniert.

Deshalb gilt immer: Einfach versuchen, den gewünschten Zugriff auf die Datei durchzuführen und die möglicherweise auftretende Exceptions fangen.

herbivore

Suchhilfe: 1000 Worte