dataGridView Spalte in Array ablegen

Gotenks

Mitglied
Hey@all

ich habe da mal ein kleines problem :/

Also ich habe ein DataGridView das mit eineer CheckboxColumn ausgestattet ist, so kann man die Datensätze/zeilen die man Speichern will selektieren :)
Doch wie schaffe ich es das ich sowohl die datei zu speichern und gleichzeitig in ein Array die ID`s der ensprechenden Zeile zu kopieren?

C# Code:
Code:
string output = speicher_Ort + txt1.Text + ".csv";
            StreamWriter streamWriter = new StreamWriter(@output, false);

            for (int r = 0; r < dataGridView1.Rows.Count; r++)
            {
                if (Convert.ToBoolean((dataGridView1.Rows[r].Cells["Speichern"] as DataGridViewCheckBoxCell).Value))
                {
                    string rowValue = "";
                    for (int c = 1; c < dataGridView1.ColumnCount; c++)
                    {
                        rowValue += "\"" + dataGridView1.Rows[r].Cells[ c].Value + "\";";
                    }
                    streamWriter.WriteLine(rowValue);

                    int[] id = new int[dataGridView1.SelectedCells.Count];

                    for (int i = 0; i < dataGridView1.SelectedCells.Count; i++)
                       id[i] = Convert.ToInt32(dataGridView1[1, i].Value);
                    
                    lbl.Text = id.Length.ToString();    //hier soll er als nachweis mir anzeigen ob sich werte in diesem array befinden
                }
            }
            streamWriter.Close();

Also meine ID Spalte befindet sich an Position 1 im DGV, weil auf 0 die Checkbox Column ist.
Das speichern als CSV-Datei kein problem, nur schaffe ich das nicht das die ID's in dem Array abgelegt werden ****?

Und wie kann ich das machen das die ID's auch nach WinForms neustart noch drinne sind, denn das Array soll verglichen werden, also irgendwann wird das array sicherlich über 1000 ID's haben aber das sollte kein problem sein.

Also kann mir villeicht jemand bei diesen problemen Helfen?
 

Turri

Erfahrenes Mitglied
Hallo,

die innere for Schleife brauchst du nicht.
Mit der äusseren gehst du ja sowieso schon alle Elemente durch.
Ich würde das Problem mit einer Liste lösen, da kannst du Ids einfach hinzufügen:
Ausserdem legst du immer nur ein "lokales Array" an.
Das ist nach dem verlassen äusseren For Schleife nicht mehr vorhanden.
C#:
string output = speicher_Ort + txt1.Text + ".csv";
StreamWriter streamWriter = new StreamWriter(@output, false);
List<int> ids = new List<int>();
for (int r = 0; r < dataGridView1.Rows.Count; r++)
{
    if (Convert.ToBoolean((dataGridView1.Rows[r].Cells["Speichern"] as DataGridViewCheckBoxCell).Value))
    {
        string rowValue = "";
        for (int c = 1; c < dataGridView1.ColumnCount; c++)
        {
            rowValue += "\"" + dataGridView1.Rows[r].Cells[ c].Value + "\";";
        }
        streamWriter.WriteLine(rowValue);
        // Durch den If weiter oben kommt man hier nur hin, wenn die Id Selektiert ist
        ids.Add(Convert.ToInt32(dataGridView1[1, r].Value));  // die id einfach in die Liste einfügen
        // den "Nachweis" habe ich nach unten verschoben, der würde sich mit jedem selektierten Element ja sonst ändern... 
        // es reicht aber, es am Ende zu sehen
    }
}
int[] id = ids.ToArray();  // Als Array
lbl.Text = id.Length.ToString();    //hier soll er als nachweis mir anzeigen ob sich werte in diesem array befinden
streamWriter.Close();
 
Zuletzt bearbeitet:

Gotenks

Mitglied
Herzlichen Dank :)

Und meine zweite frage, sind in dem array jz auch nach neustart von WinForms immernoch die ID's vorhanden?

den ich möchte nun dieses array an einer anderen stelle wieder benutzen(mit den gespeicherten inhalt nach dem klick) als Blacklist für ein dataTable.
Es soll so benutzt werden, dass das DataTable die ID's die in dem Array sind nicht mehr zu dem DataTable hinzufügen soll, weil diese schon gespeichrt wurden sind :)

Lg
 

Turri

Erfahrenes Mitglied
Hallo,

was meinst du mit dem Neustart von WinForms?
Wenn du deine Anwendung beendest, dann musst du die IDs vorher in einer Datei speichern die beim neustarten der Anwendung wieder geladen wird und dabei die ID-Liste wieder befült.

Wenn du die IDs noch an anderer Stelle brauchst, dann kann es sein, das die ID-Liste direkt in der Form-klasse angelegt werden müsste. Dazu müsste man aber mehr Code von dir sehen, wo die IDs nocht gebraucht werden.
 

Gotenks

Mitglied
Danke für deine Antwort.

habe mir schon gedacht das ich das in eine Datei speichern muss :/ weiß halt nicht wie das geht, ist das genaus so einfach wie das schreiben eines XML Dokuments bei Datatable?
Hier ist der Code zum beschreiben eines XML Codes, mit DataTable:
Code:
// zum Schreiben
temp_DT.TableName = "temp";
temp_DT.WriteXml("datatable.xml", XmlWriteMode.WriteSchema);

//zum lesen
temp_DT.ReadXml("datatable.xml")

//habe ich von dem User rd4eva

Also kann ich auch so die ID's in ein XML Dokument schreiben und danach einfach laden?

Welche Code Stelle willst du denn, habe das noch nicht eingebaut, denn muss ja erst die ID's an der besagten stelle laden und danach vergleichen.

LG
 

Turri

Erfahrenes Mitglied
Hallo,

das laden/speichern brauchst du ja nur beim Anwendungs-start und beenden,
ansonsten arbeitest du ja direkt mit der ID-Liste weiter.
Aber hier schonmal 1 kleines einfaches Beispiel zum laden und speichern.
Prüfungen, ob die Datei schon vorhanden ist etc, habe ich der Einfachheit aber weggelassen.
C#:
using System.IO;
....
// zum speichern
using (StreamWriter writer = new StreamWriter("C:\\Test.csv"))
{
    foreach (int i in ids)
    {
        writer.WriteLine(i.ToString());
    }
}

// zum laden
ids.Clear(); // falls was drin war...
using (StreamReader reader = new StreamReader("C:\\Test.csv"))
{
    string content = reader.ReadToEnd();
                
    foreach (string id in content.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
    {
        ids.Add(Convert.ToInt32(id));
    }
}
 

Gotenks

Mitglied
WOW :) Cool :) Dankeee

also wenn ich diesen Code von dir bei mir einbaue(form1_Load), dann lädt er die ID's aus einer seperaten .csv datei?
Somit sind in der List nur die Id's die auch vorher gespeichert wurden sind?

C#:
private void Form1_Load(object sender, EventArgs e)
        {
            //hier kommt dein code rein...
        }


private void button2_Click(object sender, EventArgs e)
                {
            string output = speicher_Ort + txt1.Text + ".csv";
            StreamWriter streamWriter = new StreamWriter(@output, false);
            List<int> ids = new List<int>();
            for (int r = 0; r < dataGridView1.Rows.Count; r++)
            {
                if (Convert.ToBoolean((dataGridView1.Rows[r].Cells["Speichern"] as DataGridViewCheckBoxCell).Value))
                {
                    string rowValue = "";
                    for (int c = 1; c < dataGridView1.ColumnCount; c++)
                    {
                        rowValue += "\"" + dataGridView1.Rows[r].Cells[ c].Value + "\";";
                    }
                    streamWriter.WriteLine(rowValue);
                    ids.Add(Convert.ToInt32(dataGridView1[1, r].Value));  
                }
            }
            int[] id = ids.ToArray();  
            lbl.Text = id.Length.ToString();               
            streamWriter.Close();
        }
 
 
 
private void button3_Click(object sender, EventArgs e)
        {

// hier wird zunächst der ganze SQl kram gemacht, SQL DataAdapter,Dataset etc.
 
            DataTable a_table = result.Tables[0];
            DataTable b_table = result.Tables[1];
            DataTable haupt_DT = tables.result_DT(a_table, b_table);
            DataTable temp_DT = tables.temp_DT();  
 
            DataColumn[] primArray = new DataColumn[1];
            primArray[0] = haupt_DT.Columns["ID"];
            haupt_DT.PrimaryKey = primArray; 

//und an dieser stellen sollen die ID's aus der List mit dem haupt_DT verglichen werden und wenn eine ID's vorkommt die schon in der LIST drinn steht soll sie nicht mehr angezeigt werden.
           
            dataGridView1.DataSource = haupt_DT; 

            DataGridViewCheckBoxColumn checkBox = new DataGridViewCheckBoxColumn();
            checkBox.HeaderText = "Speichern";
            checkBox.Name = "Speichern";
            checkBox.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
            dataGridView1.Columns.Insert(0, checkBox);
            this.dataGridView1.AutoGenerateColumns = true;
        }

Das die letzte frage dann fertig, würde mich freuen wenn ich recht habe :)

LG

ps.: Danke für das lesen bis hierhin
 

Turri

Erfahrenes Mitglied
Hallo,

ja stimmt, nur in deinem Fall musst du die Liste in der Form Klasse anlegen und nicht irgendwo lokal.

// sollte grob so aussehen
C#:
public partial class Form1 : Form
{
    List<int> ids = null;
    public Form1()
    {
        InitializeComponent();
        this.ids = new List<int>();
....
Also die Zeile mit dem "new List..." aus dem Button 2 Click raus und rein in den Konstruktor...
Dann müsste das gehen.
Prüfe aber ab, ob die Datei schon existiert, da du sonst eine FileNotFoundException bekommst beim laden.

CSV ist eigentlich eine falsche Datei-Endung, die Werte stehen untereinander in der Datei. :)
 

Gotenks

Mitglied
hey..Danke

hier mein code:
C#:
        List<int> ids = null;
   
        private void Form1_Load(object sender, EventArgs e)
        {

            ids = new List<int>();
            if (File.Exists(@"C:\\Users\\Default\\Desktop\\ID's.csv"))
            {
                using (StreamReader reader = new StreamReader("C:\\Users\\Default\\Desktop\\ID's.csv"))
                {
                    string content = reader.ReadToEnd();

                    foreach (string id in content.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
                    {
                        ids.Add(Convert.ToInt32(id));   // hier kommt der Fehler: Die Eingabezeichenfolge hat das falsche format. ? ? ? 
                    }
                }
                int[] ID = ids.ToArray();
                lbl.Text = ID.Length.ToString();
            }
            else
            {
                MessageBox.Show("Datei nicht Vorhanden", "Achtung");
            }
        }


        private void button2_Click(object sender, EventArgs e)
        {
            string output = speicher_Ort + txt1.Text + ".csv";
            StreamWriter streamWriter = new StreamWriter(@output, false);
            this.ids = new List<int>();
            for (int r = 0; r < dataGridView1.Rows.Count; r++)
            {
                if (Convert.ToBoolean((dataGridView1.Rows[r].Cells["Speichern"] as DataGridViewCheckBoxCell).Value))
                {
                    string rowValue = "";
                    for (int c = 1; c < dataGridView1.ColumnCount; c++)
                    {
                        rowValue += "\"" + dataGridView1.Rows[r].Cells[ c].Value + "\";";
                    }
                    streamWriter.WriteLine(rowValue);

                    ids.Add(Convert.ToInt32(dataGridView1[1, r].Value));

                    using (StreamWriter writer = new StreamWriter("C:\\Users\\Default\\Desktop\\ID.csv"))
                    {
                        foreach (int i in ids)
                        {
                            writer.WriteLine(i.ToString());
                        }
                    }


                    int[] id = ids.ToArray(); 
                    lbl.Text = id.Length.ToString(); 
                    streamWriter.Close();
                }
            }
        }

CSV ist eigentlich eine falsche Datei-Endung, die Werte stehen untereinander in der Datei. :)

Kann ich dann einfach .xml machen? und wieso ist das nicht gut? macht er fehler beim einlsen?

Und jz die letzte abschluss frage:
Wie kann ich das gelade writer(List-) Objekt mit einer datatable vergleichen und die ID's die im List-Objekt sind sollen im dataTable gelöscht werden, oder im dgv einfach NICHT angezeigt werden?

Die ID-Spalte befindet sich an erster position im Datatable, also 0 (ist auch typ int) :)

Hoffe hilfst mir das letzte mal :)

Danke aber bis hierhin ^^
Lg
 
Zuletzt bearbeitet:

Turri

Erfahrenes Mitglied
Du hast noch ein paar Bugs drin...

Im Button2 Click darfst du die Liste nicht nochmal anlegen.
Das raus:
C#:
this.ids = new List<int>();
Diese Zeile kann auch raus, ich dachte am Anfang du willst zwingend ein Array haben...
war aber nicht der Fall...
Weg mit der Zeile. :)
C#:
int[] id = ids.ToArray();

Zum entfernen der Zeilen mit der ID welche ja an Stelle 0 steht:
C#:
foreach (int id in ids)
{
    DataGridViewRow row = dataGridView1.Rows
                            .Cast<DataGridViewRow>()
                            .Where(r => r.Cells[0].Value.ToString().Equals(id.ToString()))
                            .First();

    if (row != null)
        dataGridView1.Rows.Remove(row);
}
Müsste so klappen...

Als Dateiendung würde ich in deinem Fall einfach txt machen.
Du kannst auch eine andere Endeung verwenden,
aber eigentlich sollte die Endung dem Inhalt entsprechen.