kostenloser Webspace werbefrei: lima-city


C# komisches verhalten DataGridView

lima-cityForumProgrammiersprachenProgrammieren mit .NET & Mono

  1. Autor dieses Themas

    tomarr

    tomarr hat kostenlosen Webspace.

    Hallo zusammen.

    Ich hab da mal ein Problem mit dme DataGridview. Und zwar ist es folgendes. Ich programmiere gerade an einem Vokabeltrainer. Um jetzt Vokabeln möglichst einfach eingeben zu können benutze ich eine Form mit einem DataGridView und zwei Spalten (Deutsch und Englisch). Soweit so OK.

    Ist nun die Eingabe der Liste von Vokabeln beendet möchte ich auf einen Button drücken der erstmal die ganzen Vokabeln in List<Vokabel> überträgt. Das mache ich weil ich die Classe Vokabel serialisiert habe um diese in meinem eigenen Format abspeichern zu können.

    Allerdings reagiert DataGridView absolut unverständlich in meinen Augen.

    Folgender Code funktioniert bisher wenigstens einigermaßen, führt aber trotzdem zu abstürzen.
    private Vokabel vok = new Vokabel();
            private List<Vokabel> Vokabeln = new List<Vokabel>();


    for (int i = 0; i < data_Eingabe.Rows.Count;i++ )
                {
                    vok.s_Deutsch = data_Eingabe.Rows[i].Cells["col_Deutsch"].Value.ToString();
                    vok.s_English = data_Eingabe.Rows[i].Cells["col_English"].Value.ToString();
                    vok.i_Phase = 1;
                    Vokabeln.Add(vok);
                }


    Die GridView hat wie gesagt zwei Spalten, links Deutsch, rechts Englisch.
    Wenn ich jetzt nichts eingebe und Speicher bekomme ich eine System.NullReferenceException in deer Zeile vok.s_Deutsch = data_Eingabe.Rows.Cells["col_Deutsch"].Value.ToString();
    Gebe ich eine Vokabel ein (Z.B. Du und You) bekomme ich ebenfalls eine System.NullReferenceException, allerdings in der Zeile vok.s_English = data_Eingabe.Rows.Cells["col_English"].Value.ToString();... was ich etwas merkwürdig finde weil es ist ja ein Wert vorhanden und der Index sollte auch stimmen.
    Gebe ich drei Vokabeln ein (Du, you und in der nächsten Zeile Ich) speichert er die erste Zeile komplett und verursacht wieder eine System.NullReferenceException für die nächste Zeile erste Zelle.

    Ich vermute mal das es daran liegen könnte das bereits eine leere Zeile vorgegeben wird sobald man etwas eingibt und dass die Zelle als leer gilt solange man den Cursor noch in dieser hat. Allerdings finde ich dieses Verhalten ein wenig unkompfortabel und seltsam fehlerträchtig.

    Gibt es da vielleicht eine bessere Möglichkeit die DataGridView in List zu schieben? Habe mit DataGridView ehrlich gesagt noch nicht viel Erfahrung. Habs halt noch nie gebraucht.
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Hallo,

    1. mehr code wäre hilfreich.
    2. deine NullReferenceException ohne werte in der Tabelle ist irgendwie klar, da du versucht den Value einer Zelle abzufragen, die nicht vorhanden ist. (Value.ToString())
    3. Schau mal beim DataGridView nach, ob dir DataBindung oder DataSource irgendwie hilft um deine Liste mit deinen Vokabeln zu haben?!

    Edit:
    4.Habe gerade noch ein test gemacht, da ich mir nicht mehr 100%ig sicher war, aber wenn du versuchst deine List damit zu füllen:
    private Vokabel vok = new Vokabel();
            private List<Vokabel> Vokabeln = new List<Vokabel>();
    
    
    
    for (int i = 0; i < data_Eingabe.Rows.Count;i++ )
                {
                    vok.s_Deutsch = data_Eingabe.Rows[i].Cells["col_Deutsch"].Value.ToString();
                    vok.s_English = data_Eingabe.Rows[i].Cells["col_English"].Value.ToString();
                    vok.i_Phase = 1;
                    Vokabeln.Add(vok);
                }

    wirst du in deiner gesamten Liste, zwar n-Einträge haben, aber diese haben alle den gleichen wert, da du nie ein neues object vom type Vokabel erstellst ;-)

    MfG Trancer

    Beitrag zuletzt geändert: 18.12.2014 12:32:57 von trancedrome
  4. Autor dieses Themas

    tomarr

    tomarr hat kostenlosen Webspace.

    Welchen Code sollte ich denn sonst noch posten. Das einzige was mir da noch einfällt wäre die Vokabel-Klasse

    using System;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Vokabeltrainer
    {
        [Serializable()]
        public class Vokabel : ISerializable
        {
            private string s_Deutsch;
            private string s_English;
            private int i_Phase;
        
            public Vokabel()
            {
            }
    
            public Vokabel(SerializationInfo info, StreamingContext ctxt)
            {
                this.s_Deutsch = (string)info.GetValue("Deutsch", typeof(string));
                this.s_English = (string)info.GetValue("English", typeof(string));
                this.i_Phase = (int)info.GetValue("Phase", typeof(int));
            }
    
            public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
            {
                info.AddValue("Deutsch", this.s_Deutsch);
                info.AddValue("English", this.s_English);
                info.AddValue("Phase", this.i_Phase);
            }
        }
    
        [Serializable()]
        public class ObjectToSerialize : ISerializable
        {
            private List<Vokabel> vokabeln;
            public List<Vokabel> Vokabeln
            {
                get { return this.vokabeln; }
                set { this.vokabeln = value; }
            }
    
            public ObjectToSerialize()
            {
            }
    
            public ObjectToSerialize(SerializationInfo info, StreamingContext ctxt)
            {
                this.vokabeln = (List<Vokabel>)info.GetValue("Vokabeln", typeof(List<Vokabel>));
            }
    
            public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
            {
                info.AddValue("Vokabeln", this.vokabeln);
            }
        }
    
        public class Serializer
        {
            public Serializer()
            {
            }
    
            public void SerializeObject(string fileName, ObjectToSerialize objectToSerialize)
            {
                Stream stream = File.Open(fileName, FileMode.OpenOrCreate);
                BinaryFormatter bFormatter = new BinaryFormatter();
                bFormatter.Serialize(stream, objectToSerialize);
                stream.Close();
            }
    
            public ObjectToSerialize DeSerializeObject(string fileName)
            {
                    ObjectToSerialize objectToSerialize;
                    Stream stream = File.Open(fileName, FileMode.Open);
                    BinaryFormatter bFormatter = new BinaryFormatter();
                    objectToSerialize = (ObjectToSerialize)bFormatter.Deserialize(stream);
                    stream.Close();
                    return objectToSerialize;
            }
        }
    }
  5. Jetzt bin ich schon gewillt den gesamten Code kennen zu lernen, dieser kleine Ausschnitt ist fast schon nichts sagend zu deinem Problem.
  6. Autor dieses Themas

    tomarr

    tomarr hat kostenlosen Webspace.

    Damit hast du fast schon den ganzen betreffenden Code. Außer dass dieser Codeteil halt in
    for (int i = 0; i < data_Eingabe.Rows.Count;i++ )
                {
                    vok.s_Deutsch = data_Eingabe.Rows[i].Cells["col_Deutsch"].Value.ToString();
                    vok.s_English = data_Eingabe.Rows[i].Cells["col_English"].Value.ToString();
                    vok.i_Phase = 1;
                    Vokabeln.Add(vok);
                }

    btn_Safe_Click steht.

    Also genau genommen so....

    private void btn_Save_Click(object sender, EventArgs e)
            {
                for (int i = 0; i < data_Eingabe.Rows.Count;i++ )
                {
                    vok.s_Deutsch = data_Eingabe.Rows[i].Cells["col_Deutsch"].Value.ToString();
                    vok.s_English = data_Eingabe.Rows[i].Cells["col_English"].Value.ToString();
                    vok.i_Phase = 1;
                    Vokabeln.Add(vok);
                }
            }


    Oder wenn du wirklich die ganze Formklasse sehen willst...

    public partial class frmVokabeleingabe : Form
        {
            private Vokabel vok = new Vokabel();
            private List<Vokabel> Vokabeln = new List<Vokabel>();
    
            public frmVokabeleingabe()
            {
                InitializeComponent();
            }
    
            private void frmVokabeleingabe_Load(object sender, EventArgs e)
            {
    
            }
    
            private void btn_Save_Click(object sender, EventArgs e)
            {
                for (int i = 0; i < data_Eingabe.Rows.Count;i++ )
                {
                    vok.s_Deutsch = data_Eingabe.Rows[i].Cells["col_Deutsch"].Value.ToString();
                    vok.s_English = data_Eingabe.Rows[i].Cells["col_English"].Value.ToString();
                    vok.i_Phase = 1;
                    Vokabeln.Add(vok);
                }
             }
        }
  7. Okay, hab versucht mir das Project nachzubauen.
    Denke ich habs ganz gut hinbekommen.

    ALSO zu deinem Problemen:
    1. Deine NullReferenceException bekommst du, weil der Value in der leeren Zeile (neue schreibbare Zeile) leer ist. Prüfen vorher ab, ob der Value ungleich null ggf string.empty ist.


    private void btn_Safe_Click(object sender, EventArgs e)
            {
                for (int i = 0; i < data_Eingabe.Rows.Count; i++)
                {
                    if (data_Eingabe.Rows[i].Cells["colDeutsch"].Value != null 
                        && data_Eingabe.Rows[i].Cells["colDeutsch"].Value.ToString() != string.Empty)
                    {
                        vok.s_Deutsch = data_Eingabe.Rows[i].Cells["colDeutsch"].Value.ToString();
                        vok.s_English = data_Eingabe.Rows[i].Cells["colEnglish"].Value.ToString();
                        vok.i_Phase = 1;
                        Vokabeln.Add(vok);
                    }
                }
            }


    ODER (nicht die beste lösung!) du ziehst von dem listen-count eine ab. (dataGridView1.Rows.Count - 1)

    2. Ich sehe da beim füllen deiner Vokabeln-Liste noch ein Problem, da du hier immer das selbe vok-Object nutzt. Damit werden die Werte immer noch ausgetauscht und das Object wieder in die Liste eingefügt.
    Zum Schluss hast du in deiner Liste folgendes:
    2.1. Deutsch: Ich; Englisch: I
    2.2. Deutsch: Ich; Englisch: I
    2.3. Deutsch: Ich; Englisch: I
    und so weiter...weil du immer im selben object die werte austauscht.
    mach es so:
    for (int i = 0; i < data_Eingabe.Rows.Count; i++)
                {
                    if (data_Eingabe.Rows[i].Cells["colDeutsch"].Value != null 
                        && data_Eingabe.Rows[i].Cells["colDeutsch"].Value.ToString() != string.Empty)
                    {
                        Vokabel vokabel = new Vokabel();
                        vokabel.s_Deutsch = data_Eingabe.Rows[i].Cells["colDeutsch"].Value.ToString();
                        vokabel.s_English = data_Eingabe.Rows[i].Cells["colEnglish"].Value.ToString();
                        vokabel.i_Phase = 1;
                        Vokabeln.Add(vokabel);
                    }
                }


    EDIT: wenn es jetzt noch Problem gibt, will ich den gesamten Code haben. Zippen und irgendwo hochladen ;-)

    Beitrag zuletzt geändert: 18.12.2014 14:24:11 von trancedrome
  8. Autor dieses Themas

    tomarr

    tomarr hat kostenlosen Webspace.

    Probiere ich mal...

    Schankedön :)
  9. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!