| Autor |
Beitrag |
Carlo Deluxe
Hält's aus hier
Beiträge: 8
|
Verfasst: Sa 14.05.11 12:48
Ich habe eine Datei Namens "MemberList.dtb" im Ordner, in dem das Programm ist. Diese Datei ist nach folgenden Muster aufgebaut:
{USERNAME}
{PASSWORT}
{RANG (INTEGER)}
{USERNAME2}
{PASSWORT2}
usw...
Diese Werte will ich auslesen und in ein DataGridView schreiben. Das klappt auch, doch im DataGridView sind nach den gefüllten Werten noch einige leere Zeilen (insgesamt sind es genau so viele zielen wie die Datei Zeilen hat). Ich benutze folgenden Code dafür:
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:
| StreamReader acc = new StreamReader(directory.GetCurrentDirectory + @"\MemberList.dtb"); int lines = 0; while((cache=acc.ReadLine())!=null) lines++; acc.BaseStream.Position = 0; while (i<lines) { i=accounts.Rows.Add(); accounts.Rows[i].Cells[0].Value = acc.ReadLine(); accounts.Rows[i].Cells[1].Value = acc.ReadLine(); cache = acc.ReadLine(); switch (cache) { case("-1"): (accounts.Rows[i].Cells[2] as DataGridViewComboBoxCell).Value = "no rights"; break; case("0"): (accounts.Rows[i].Cells[2] as DataGridViewComboBoxCell).Value = "member"; break; case("1"): (accounts.Rows[i].Cells[2] as DataGridViewComboBoxCell).Value = "helper"; break; case("2"): (accounts.Rows[i].Cells[2] as DataGridViewComboBoxCell).Value = "moderator"; break; case("3"): (accounts.Rows[i].Cells[2] as DataGridViewComboBoxCell).Value = "admin"; break; case("4"): (accounts.Rows[i].Cells[2] as DataGridViewComboBoxCell).Value = "superadmin"; break; } i++; } acc.Close(); |
Ich habe es jetzt so gelöst, dass er nach dem einlesen alle leeren Zeilen löscht, aber das muss doch auch eleganter gehen, oder?
Moderiert von Kha: Code- durch C#-Tags ersetzt
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Sa 14.05.11 15:18
| Zitat: | | aber das muss doch auch eleganter gehen, oder? |
Einfach nur den Fehler korrigieren macht es noch nicht elegant. Dafür müsstest du wahrscheinlich nur aus dem i++ in der zweiten Schleife ein i += 3 machen den 3 Zeilen in der Datei entsprechen einer Zeile im Grid.
Für mehr Eleganz solltest du eine Klasse dazwischen schalten die die Daten hält. Die direkt ins Grid zu schreiben macht das unübersichtlich und sobald du mehr mit den Daten machen willst als sie nur im Grid anzuzeigen hast du unnötig viele Probleme.
Also eine Klasse für die Account Daten erstellen.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| public enum Rang { norights = -1, member, helper, moderator, admin, superadmin };
public class Account { public string UserName { get; set; } public string Password { get; set; } public Rang Rang { get; set; } } |
und dann eine Liste dieser Klassen füllen und per Databinding in deinem Grid darstellen
C#-Quelltext 1: 2: 3: 4: 5: 6: 7:
| string[] lines = File.ReadAllLines("TextFile1.txt"); List<Account> accounts = new List<Account>();
for (int i = 2; i < lines.Length; i = i + 3) accounts.Add(new Account() { UserName = lines[i-2], Password = lines[i - 1], Rang = (Rang)Int32.Parse(lines[i]) });
meinDataGridView.DataSource = accounts; |
Was die Eleganz vielleicht reduziert aber trotzdem nötig ist, du solltest das ganze noch mit ein wenig Fehlerhandling garnieren (egal ob mein oder dein Code). Insbesondere für den Fall das die Struktur der Datei nicht stimmt.
|
|
Carlo Deluxe 
Hält's aus hier
Beiträge: 8
|
Verfasst: Sa 14.05.11 18:14
Okay, das geht soweit, danke dafür  , nur was ist, wenn ich beim Rang statt einem String eine ComboBox hab (sry, ich habe noch nicht viel mit Classes gemacht und weiß nicht viel darüber)?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Sa 14.05.11 18:31
In dem Fall kannst du die Enum Werte der DataSource deiner ComboBoxColumn einfach zuweisen. In etwa
C#-Quelltext 1:
| meinLiebeGridViewComboBoxColumn.DataSource = Enum.GetValues(typeof(Rang)); |
|
|
Carlo Deluxe 
Hält's aus hier
Beiträge: 8
|
Verfasst: Sa 14.05.11 21:24
sry, ich kapiers nicht ganz  , kannst du mir das bitte im Code zeigen?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: So 15.05.11 13:35
Nun. Dein DataGridView besteht ja aus Columns. Wenn du sagst du hast eine ComboBoxColumn hast du die im Grid vordefiniert um den Typ der Column zu ändern denn wenn ich das richtig in Erinnerung habe sind automatisch erstellte Columns immer TextBox Columns. Wenn du die Column also manuell erstellt hast weißt du auch den Variablennamen dieser Column und diese Column hat eine DataSource Property der man die Liste der Auswahlmöglichkeiten zuweisen kann.
Wo und wann du das machst ist vollkommen egal. Könntest du zum Beispiel im Konstruktor der Form machen (nach InitializeComponents) oder im Load oder Shown Event der Form.
Also einfach den Namen der Column rausfinden und deren DataSource Property die Menge der Enum Werte zuweisen. Die Liste aller Enum Werte zu bekommen ist halt die Aufgabe der Enum.GetValues Funktion der man den Typ des gewünschten Enum übergibt.
|
|
Carlo Deluxe 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mi 18.05.11 18:16
Aber ein Column hat doch gar keine DataSource Eigenschaft oder verstehe ich das jetzt falsch?
Also soll ich eine ComboBoxColumn für den Rang im Designer erstellen, und die anderen 2 werden dann automatisch erstellt?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 18.05.11 19:01
Eine ComboBoxColumn hat eine DataSource Property. Die im Designer vorzudefinieren hört sich geschickt an. Wenn dann würde ich aber gleich alle vordefinieren. Nur halb vordefinieren geht natürlich empfinde ich aber als eher nicht hilfreich.
|
|
Carlo Deluxe 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mi 18.05.11 20:27
Danke, jetzt geht es 
|
|