CSharp 2D List

Gast #3919856
Hi,

in einem DataGridView Objekt soll mit einer foreach Schleife 
festgestellt werden, welche Element in der zweiten Spalte auf true 
steht. Das funktioniert soweit. Nicht nur auf true soll geprüft werden, 
sondern auch bei false. Wie könnte dies in C# realisiert werden?
1
        List<Tuple<string, int>> stringIpAddr = new List<Tuple<string, int>>();
2

3

4
            foreach (DataGridViewRow row in dataGridView.Rows)
5
            {
6
                if (Convert.ToBoolean(row.Cells["Use"].Value) == true)
7
                {
8
                    stringIpAddr[row.Index] = Tuple.Create(row.Cells["IPDestination"].Value.ToString(), 1);
9
                }
10
            }

Sobald ich eine else Bedingung in der foreach Schleife hinzufüge, 
erscheint eine Fehlermeldung

-> NullReferenceException wurde nicht behandelt. Der Objektverweis wurde 
nicht auf eine Objektinstanz festgelegt.
1
            foreach (DataGridViewRow row in dataGridView.Rows)
2
            {
3
                if (Convert.ToBoolean(row.Cells["Use"].Value) == true)
4
                {
5
                    stringIpAddr[row.Index] = Tuple.Create(row.Cells["IPDestination"].Value.ToString(), 1);
6
                }
7
                else
8
                {
9
                    stringIpAddr[row.Index] = Tuple.Create(row.Cells["IPDestination"].Value.ToString(), 0);
10
                }
11
            }
Gast
Hab mir überlegt die anders zu lösen.

Wie kann ich nur auf die zweite Spalte zugreifen (schreiben)?
1
List<Tuple<string, int>> stringIpAddr = new List<Tuple<string, int>>();
Gast
So funktioniert es nun:
1
            foreach (DataGridViewRow row in dataGridView.Rows)
2
            {
3
                if (Convert.ToBoolean(row.Cells["Use"].Value) == false)
4
                {
5
                    if(row.Index < TableIpAddr.Count) 
6
                        TableIpAddr[row.Index] = Tuple.Create(row.Cells["IPDestination"].Value.ToString(), 0);
7
                }
8
                else if (Convert.ToBoolean(row.Cells["Use"].Value) == true)
9
                {
10
                    TableIpAddr[row.Index] = Tuple.Create(row.Cells["IPDestination"].Value.ToString(), 1);
11
                }
12
            }
Gast
Ich würde dann aber (falls du es noch nicht gemacht hast) auch die 
Anzahl der Zeilen begrenzen und nicht stillschweigend Einträge 
ignorieren. Man könnte auch prüfen, ob im IP-Feld ein Wert vorhanden 
ist, bevor man ToString aufruft, da das Programm sonst u.U. mit einer 
NullReferenceException abstürzt. Der Use-Wert kann eigentlich nur true 
oder false sein, also ist der else-Zweig sinnlos.
Wenn du die Anzahl der Spalten nicht begrenzt, könntest du List.Add 
nehmen (sonst wäre auch ein einfaches Array möglich). Warum du statt 
bool int verwendest, kann man nicht ohne weiteren Code erkennen ...
1
foreach (DataGridViewRow row in dataGridView.Rows)
2
{
3
  var ipDestination = row.Cells["IPDestination"].Value;
4
  if (ipDestination != null)
5
  {
6
    bool use = Convert.ToBoolean(row.Cells["Use"].Value);
7
    TableIpAddr.Add(Tuple.Create(ipDestination.ToString(), use ? 1 : 0));
8
  }
9
}

Oder per LINQ (in diesem Fall aber nicht besser, denke ich):
1
TableIpAddr = (from row in dataGridView.Rows.Cast<DataGridViewRow>()
2
               let stringIpAddr = row.Cells["IPDestination"].Value
3
               where stringIpAddr != null
4
               let use = Convert.ToBoolean(row.Cells["Use"].Value) ? 1 : 0
5
               select Tuple.Create(stringIpAddr.ToString(), use))
6
               .ToList();


Evtl. wäre es dann auch sinnvoll, die eigentliche "Arbeitstabelle" von 
dieser Methode bzw. der Liste TableIpAddr zu trennen und bei der 
Übernahme der Daten an anderer Stelle dann zu reagieren, falls die 
Anzahl der Einträge sich geändert hat (anstatt irgendwo in einer Form, 
also im User-Interface-Code, das Ganze als "if (row.Index < 
TableIpAddr.Count)" zu verstecken).

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 11 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.