Autor Beitrag
Ritzeratze
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: Sa 14.03.15 14:46 
Hi, ich habe eine dat-Datei die Spielpunkte und Namen enthält.

Diese Datei möchte ich in Textboxen einlesen.
Leider erhalte ich immer einen System.IO.EndofStream Eception.
Wahrscheinlich, weil ich über das EOF hinauslese.
Kann mir jemand einen Tipp geben? Danke


Gruss Ritze

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Moderiert von user profile iconTh69: Code- durch C#-Tags ersetzt


Zuletzt bearbeitet von Ritzeratze am Mi 01.04.15 22:28, insgesamt 2-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 14.03.15 14:57 
Wenn du das mit einem ähnlichen Verfahren in die Datei geschrieben hast solltest du uns das auch zeigen.
Die Anzahl BinaryWriter.Write(s) beim Erzeugen der Datei muss schon zu den BinaryReader.ReadString(s) passen.

Nebenbei das sieht für mich schon sehr nach zufälliger Funktionsweise aus wenn man es denn so zum funktionieren bekommt.
Du solltest es nicht von der Menge und Reihenfolge der Controls auf der Form abhängig machen.

Edit: Sollte die angehängte Form irgendwas mit dem Problem zu tun haben?
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: So 15.03.15 12:11 
Moin Ralf,

Danke für Deine Antwort.
Die Werte die in den textboxen geschrieben werden sollen kommen aus folgender Methode

Beim Lesen der Datei, um die Textboxen zu füllen habe ich ja nur den binaryReader.ReadString. Die Punktzahl (GetPunkte) in der Scoredat ist alledings int, der Name (GetName) ein String. Das kann dann nicht funktionieren. Wie kann ich aber die Werte mit der binaryReader Methode auslesen und in die Textboxen schreiben?

Gruss Ritzeratze

Moderiert von user profile iconTh69: Code- durch C#-Tags ersetzt


Zuletzt bearbeitet von Ritzeratze am Mi 01.04.15 22:29, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 15.03.15 14:13 
a.) Es gibt sehr einfache Methoden Datenstrukturen in eine Datei zu serialisieren. Im Framework direkt zum Beispiel über den XmlSerializer oder den JsonSerializer die nehmen dir eigentlich vieles von dem ab was du hier versuchst selbst zu machen.
b.) Wenn du eine Datenstruktur wegschreibst (bestenliste) sollte das lesen auch wieder diese Datenstruktur erzeugen (was das konkret auch immer für eine Datenstruktur ist) und nicht eine irgendwie geartete UI direkt füllen.

Jetzt zu deinem Verfahren du willst selbst binär in eine Datei schreiben. Dazu mußt du dafür sorgen das du das was du reinschreibst auch wieder lesen kannst. Das beginnt damit das du wissen musst wie viele Einträge überhaupt drin sind. Das kann man zum Beispiel machen in dem man als erstes die Anzahl in die Datei schreibt (Dazu müßtest du deinen Schreibcode nur ergänzen und zuerst anzahl in die Datei schreiben).

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
BestenListe bestenListe = new BestenListe(); // irgendwas List<T>, Array wass immer du auch  benutzt hast ich nehme mal List<T> an
using(FileStream stream = new FileStream(fileName, FileMode.Open))
{
    using(BinaryReader reader = new BinaryReader(stream))
    {
        for (int i = 0; i < reader.ReadInt32(); i++)
        {
             var entry = new BestenListeEntry();

             entry.Punkte = reader.ReadInt32();
             entry.Name = reader.ReadString();
             bestenListe.Add(entry);
        }
    }
}


Und jetzt gehst du hin nimmst das neue bestenListe Objekt transportierst es zur UI und befüllst die UI damit.
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: So 15.03.15 14:36 
Hi Ralf,

sitze vielleicht schon zu lange daren. MIttlerweilen habe ich mich dabei ein bißchen festgefahren. Die Datei Bestenliste (score.dat) exitsiert ja bereits, d.h. hier sind 10 Objekte mit jeweils Punkten und Namen vorgegeben. Diese möchte ich auslesen und in die Form schreiben, um die bestehenden Daten zu Manipulieren. Danach wieder ind die score.dat zurückschreiben.

Gruss Ritzeratze
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 15.03.15 16:32 
Zitat:
d.h. hier sind 10 Objekte mit jeweils Punkten und Namen vorgegeben


Immer oder nur in dieser speziellen Datei die du gerade zur Hand hast?
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: So 15.03.15 18:44 
Hi Ralf,

ich habe versucht, das ganze von hinten aufzurollen. Die Werte in ein Array gepackt und danach ausgelesen und den textboxen zugewiesen.
Aber irgendwo ist noch ein Haken. Die Werte werden gefüllt, aber nicht in der gewünschten Reihenfolge. Ni nicht mehr weit davon entfernt:-)



Moderiert von user profile iconTh69: Code- durch C#-Tags ersetzt


Zuletzt bearbeitet von Ritzeratze am Mi 01.04.15 22:26, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 15.03.15 20:40 
Ich kann nur wiederholen das über die Controls zu iterieren und zu hoffen das du die in irgendeiner sinnvollen Reihenfolgen geliefert bekommst ein reines Glückspiel ist.
Mach irgendwas gezielteres. z.B.

a.) Erstelle dir eine Klasse die Name und Punktzahl hält
b.) Erstell dir davon eine Liste oder Array passender Länge.
c.) Schreib und Lies deiner Daten aus dieser Liste. (Halt die UI da raus)
d.) Sortiere diese Liste falls nötig. (z.B. nach Punktzahl)
e.) Erstelle eine UI der du diese Liste/Array sauber zuordnen und in der richtigen Reihenfolge anzeigen kannst.
Z.B in einem DataGridView Control, ListBox, ListView, passende UserControls in einem TableLayout- bzw. FlowLayoutPanel was auch immer.
Aber nicht einfach viele TextBoxen auf die Form werfen und hoffen Form.Controls würde die gerade in der Reihenfolge liefern wie du es gerade brauchst.
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: So 15.03.15 21:07 
Würde ich ja gerne machen. Leider sind das ein paar gewisse Vorgaben.
In einen Array habe ich ja die Datei score.dat eingelesen. Diese werden ja auch wieder ausgegeben.
Allerdings erst die Namen dann die Punkte. Ok, die Form mit den Textboxen ist vielleicht die blödeste Variante (leider die Vorgabe)
und mit DataGrid kenn ich mich leider noch nicht aus.

Werde das wohl oder übel hintricksen müßen.
Ritzeratze
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: So 15.03.15 23:59 
Zur Klärung: der foreach-Schleifenoperator liefert irgendeine, nicht vorhersehbare und nicht immer reproduzierbare Reihenfolge zurück. Das ist das eigentliche Problem hier.

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.

Für diesen Beitrag haben gedankt: C#
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Mo 16.03.15 13:09 
Auf Stackoverflow steht, dass die Folge einer IList immer der Reihenfolge des Indexers entspricht.

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 16.03.15 15:17 
Das war nicht das worauf ich hinaus wollte. Egal über welche Klasse man iteriert kein Enumerator wird einen Zufallsgenerator implementiert haben. Die haben schon alle ein eindeutiges wiederholbares Verhalten. So natürlich auch die ControlCollection. So wie man Controls reinwirft kommen die auch wieder raus. Soweit kein Problem. Der Winforms Editor bestimmt aber die Reihenfolge und üblicherweise nicht der Programmierer. Außer der Programmierer legt selbst Hand an den Designer Code bzw. kontrolliert selbst ständig über die Dokument Outline die Reihenfolge. Das macht ein erfahrener Programmierer bestimmt schon mal aber kein typischer Entwickler. Der schubst seine Controls im Designer auf der Form rum und hat schwupp-di-wupp die Reihenfolge in der ControlCollection geändert ohne das es normalerweise Auswirkungen hätte außer das das Control woanders liegt.

In dieser Form über Controls iterieren und Daten zuweisen ist daneben. Insofern werde ich keinen Code posten den hier irgendwer einfach Copy&Paste-Like nehmen kann ohne den Thread gelesen zu haben und zu verstehen das das genau das ist was man nicht tun sollte. Ich will aber nicht keinen Hinweis geben. Insofern könntest du die Reihenfolge fixieren in dem du die Controls passend benammst und dann im foreach die Controls Liste passend sortierst
(z.B. this.Controls.OfType<TextBox>().OrderBy(x=>x.Name)) bevor du darauf zugreifst. Aber dann beim Lesen und Schreiben gleich. Nicht mal so und dann wieder anders. Und danach merken das man das so im wirklichen Programmierer leben nie so tun würde.


@C# : List hat ein eindeutiges Verhalten da es ja eine eindeutige Implementierung hat. IList ist nur ein Interface. Und ohne Implementierung kannst du gar nicht vorhersagen wie der sich verhält. Kommt halt drauf an was sich der Implementor ausdenkt. Du wolltest bestimt von List<T> sprechen und nicht von IList. Die ControlCollection ist kein List<T> (Verhalten wird aber ähnlich sein bezüglich des Enumerators)

Für diesen Beitrag haben gedankt: C#
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: Mi 18.03.15 22:14 
Moin,

nachdem ich mir nochmal die Textboxen Thematik angeschaut, diese Threads in Ruhe gelesen und im Netz gesucht hatte (dynamische Erstellung von Textboxen hat mir sehr gut gefallen) hatte ich nochmal versucht mit meinem Lösungsanstaz die eingefügten Textboxen auf der Form mit der entsprechenden .dat Datei zu befüllen, was auch geklappt hat. Allerdings hatte ich dann die Controls nur verschoben, und beim Versuch die Werte in die .Dat Datei zurückzuschreiben, bin ich wieder auf die Nase gefallen. Bei dieser Aktion habe ich gelernt, das es so nicht der idealste Weg ist.

Ich würde gern einen anderen Ansatz verfolgen, finde nur nicht den richtigen Anfang wie ich mit den Textboxen umgehen soll. Lege ich zwei Arrays für die Textboxen an (eins für die Punktzahl (int), eins für die Spielernamen (string)? Datagridview scheidet aus, weil ich noch nicht so weit bin. Welche Möglichkeiten hätte ich noch? Mir würde ein Ansatz sehr helfen, den Rest möchte ich selber raustüfteln.

Gruss Ritze
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 18.03.15 23:06 
Das hilfreiche Stichwort ist wahrscheinlich UserControl.

Punktzahl und Name gehört ja zusammen. Sie bilden zusammen eine logische Einheit und sollten deshalb auch als solches in einer Klasse zusammengefasst werden. Nennen wir diese Klasse mal im folgenden Score. Ähnlich kann man auch in der UI vorgehen. Erstell dir ein UserControl das die 2 TextBoxen für Punktzahl und Name enthält (und vielleicht passenden Labels dazu) und gibt diesem UserControl eine Methode der man eine Instanz der Score Klasse übergeben kann. Diese Methode(Property) nimmt also die Score Klasse entgegen und verteilt die enthaltenen Werte auf die beiden TextBoxen. Nennen wir dieses UserControl im folgenden mal das ScoreControl.

Nun möchtest du aber eine ganze Liste anzeigen. Also verwalten wir eine Liste der Score Klasse. Wenn die Anzahl Einträge in deiner BestenListe fix ist dann nimm eine entsprechend langes Array ansonsten lieber eine List<Score>. Diese Liste lässt sich nebenbei dann sehr leicht persistieren (z.B. über einen XmlSerializer oder den JsonSerializer). Auf der Form die die Bestenliste anzeigt musst du nun entsprechend der Länge der Bestenliste ScoreControl(s) erzeugen. Du hast ja selbst schon von dynamischer Erstellung gesprochen man sollte es eben nur nicht mit den einzelnen TextBoxen machen sondern eben mit einer sinnvollen Gruppierung sich wiederholenden Textboxen eben das genannte ScoreControl. Also über dein Bestenliste iterieren (genauer über die nach der Punktzahl sortierten Bestenliste) und je Eintrag ein ScoreControl erzeugen die Score Instanz zuweisen und das ScoreControl richtig auf der Form positionieren. Fürs Positionieren gibts diverse Lösungen entweder selbst einfach die Position berechnen und die Location Property des ScoreControl(s) passend setzen oder eben eins der LayoutPanel verwenden die dann die einzelnen ScoreControl(s) automatisch anordnen (wenn man die richtig einstellt bekommt man einfach alle Controls im LayoutPanel Top-Down aufgereit in der Reihenfolge in der sie hinzugefügt wurden).
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: Mi 18.03.15 23:45 
Hallo Ralf,

Danke für Deine Ausführungen. Allerdings bin ich jetzt komplett off :-)
vielleicht habe ich mich falsch ausgedrückt, oder ich habe anfänglich mein Problem nicht richtig geschildert. Ich versuche es nochmal. Bin allerdings auch schon kurz davor mein ganzes Studium hinzuschmeissen.

Im Hauptspiel werden Spielpunkte und Spielernamen in der Klasse Score ermittelt. In einer separaten Klasse wird die Bestenliste mit jeweils 10 festen Plätzen (Spielername und Spielpunkte) verwaltet. und in die Datei score.dat geschrieben.

Nun soll in einem separaten Projekt ein Formular entworfen werden, das auf die score.dat zugreift , die Werte aus der Bestenliste anzeigt, die Werte hier maniupulierbar sind und dann wieder in die score.dat geschrieben werden kann. Wenn ich das Hauptspiel wieder aufrufe sollen in der Bestenliste die manipulierten Werte angezeigt werden.

Gruss Ritze. ( Ich prügel mir jetzt erstmal ne Flasche Rotwein rein)
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 19.03.15 10:52 
Hallo,

dann ist aber wirklich hier ein DataGridView besser geeignet (anstatt selber 10 Controls zu erstellen).
Der Code wäre dann einfach
ausblenden C#-Quelltext
1:
2:
3:
List<Score> scores = ReadScoresFromFile();

dataGridView.DataSource = scores;

Tada!

Da AutoGenerateColumns standardmäßig auf true steht, werden dann einfach alle öffentlichen Eigenschaften (public properties) als Spalten angezeigt, d.h. deine Score-Klasse braucht dann eben nur Name und Punkte als Eigenschaften.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 19.03.15 11:54 
Zitat:
In einer separaten Klasse wird die Bestenliste mit jeweils 10 festen Plätzen (Spielername und Spielpunkte) verwaltet. und in die Datei score.dat geschrieben.


Wenn die das lesen auch beherrscht kann ist das super ;) Die Klasse kann man dann ja ruhig an verschiedenen Stellen von mir aus auch in verschiedenen Projekten benutzen.

Zitat:
Nun soll in einem separaten Projekt ein Formular entworfen werden, das auf die score.dat zugreift, die Werte aus der Bestenliste anzeigt, die Werte hier maniupulierbar sind und dann wieder in die score.dat geschrieben werden kann


Dein obige Klasse ist dann ja der richtige Kandidat. Die mußt du halt nur anzeigen.
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: Sa 21.03.15 16:39 
Moin,

Danke für Eure Unterstützung. Aber das Datagridview scheidet aus, weil die Vorgabe Textboxen sind.
Ich kann die Werte auch auslesen und in die textboxen schreiben, aber leider gibt es dann eine
System.IO.IOException. Wenn ich die Datei im Editor anschaue, stehen die geänderten Werte allerdings richtig drin. Komme da leider ohne Hilfe nicht weiter.


Gruss Ritze
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 21.03.15 18:46 
Dann musst du zeigen was du hast. Am besten vielleicht das Projekt auf die wesentlichen Teile reduzieren, aber lauffähig halten, und dann hier anhängen.
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: Sa 21.03.15 21:32 
OK.

Pong ist das Hauptprogramm. Schummeleditor das Manipulationsprogramm