Laden...

Forenbeiträge von juetho Ingesamt 3.331 Beiträge

14.02.2010 - 10:22 Uhr

Hallo,

ToString ist in diesem Fall sowieso ein unnötiger/unsinniger Umweg: Du weißt, dass sqlReader["price"] einen double-Wert enthält. Also genügt ein einfacher cast:

double price = (double)sqlReader["price"];

Aber Tom hat recht: GetDouble ist der sichere Weg und decimal vermutlich besser.

Gruß Jürgen

13.02.2010 - 18:06 Uhr

SELECT-Befehl

Dürfen wir nicht erfahren, wie der lautet? Irgendwo muss doch WeekdayName benutzt werden?

Was soll eigentlich FillDa sein?

Immer diese Nachfragen 🙄 Jürgen

13.02.2010 - 17:32 Uhr

Hallo,

bei dieser Situation musst du uns schon genauer sagen, wo und wie du die Daten abholst: SELECT-Befehl, Einbindung in die C#-Klassen und Methoden.

WeekdayName gehört zum Namespace Microsoft.VisualBasic, ist also unter C# sowieso etwas fragwürdig.

Jürgen

11.02.2010 - 16:44 Uhr

Hallo,

das Speichern neuer Datensätze kann üblicherweise nicht am Anfang (im Load-Ereignis) erfolgen, sondern erst am Ende, nachdem neue Datensätze eingegeben wurden. Normalerweise werden also (wenn du schon vom DataGridView redest) neue Zeilen dort eingegeben, dann wird ein Button "Speichern" gedrückt, und damit sollen die Daten an die DB übergeben werden. Also ist dieses Button.Click die richtige Stelle.

Der Hauptmangel deines Codes scheint darin zu liegen, dass die Parameter nicht mit den Spalten der DataTable verknüpft werden. Du brauchst einen anderen Konstruktor, siehe [Artikelserie] Parameter von SQL Befehlen bei den "Ergänzenden Hinweisen".

Weitere Probleme:

  1. Das Thema hat nichts mit dem DGV zu tun, gehört also auch nicht in das Unterforum WinForms, sondern zu Datenbanken. Bitte die Beschreibung genauer beachten!
  2. Sowohl die DbConnection als auch der DbDataAdapter sind nur kurzfristig zu erstellen, siehe [Artikel] Ressourcen schonen - Datenbanken richtig öffnen und schließen
  3. C#-Code ist mit dem #-Button zu markieren.
  4. Nicht der DataAdapter wird an das DGV gebunden, sondern die damit gefüllte DataTable. Das ist hier zwar irrelevant, aber etwas mehr Genauigkeit ist immer von Vorteil.

Gruß Jürgen

11.02.2010 - 13:21 Uhr

Wer lesen kann, ist sehr im Vorteil. Alles klar! Jürgen

11.02.2010 - 13:01 Uhr

Hallo,

ich stolpere gerade über AcceptChanges: Willst du das wirklich bewusst aufrufen?

Das ist entgegen dem üblichen Sprachgebrauch keine Anweisung des Benutzers bzw. Programmierers an das DataSet, dass die Änderungen gültig sein und übernommen werden sollen; vielmehr ist es die Festlegung für das DataSet, dass die Änderungen als erledigt angesehen werden und bei späterem Update übergangen werden sollen.

Mit deinem sonstigen Vorgehen mit TreeView usw. habe ich keine Erfahrung, deshalb kann ich zum Thema selbst fast nichts beitragen. Aber bei AcceptChanges wurde ich stutzig. Jürgen

11.02.2010 - 12:54 Uhr

... und bedenke, dass ex.ToString sowie ggf. ex.InnerException mehr Informationen liefern als ex.Message.

Gruß Jürgen

11.02.2010 - 12:52 Uhr

@278278
Herzlich willkommen!

@Jack
Es gibt nur den Vorschlag, mit Directory.GetFiles zu arbeiten: Weil dich nur die Datei- und Pfadnamen interessieren, brauchst du nur die Strings und nicht FileInfo. Um die genauere Prüfung in der Schleife kommst du so oder so nicht herum.

Eine eigene Klasse ist sinnvoll, wenn du auch in anderen Situationen Pfade nach Dateien durchsuchen musst. Aber das kannst nur du entscheiden.

Gruß Jürgen

10.02.2010 - 15:14 Uhr

Hallo und willkommen,

  1. Du solltest die Forumsregeln durchlesen: Wie poste ich richtig?
  2. Du solltest (wie dort gefordert) die Suche verwenden, z.B. nach Textdatei zeile löschen
  3. Du solltest die dort genannten Vorschläge benutzen.

Jürgen

07.02.2010 - 20:40 Uhr

Ich hoffe, das ist kein echter Code. Andernfalls würde ich ernsthaft fragen, warum die boolsche Variable in beiden if-Zweigen separiert deklariert wird und sowohl diese Zuweisung als auch das Schreiben in Label.Text in jedem Durchgang der Schleife neu erfolgen.

Kürzer ginge es so:

            bool grossbuchstaben;
            for (int i = 0; i < laenge; i++)
            {
                grossbuchstaben = Char.IsUpper(passwort[i]);
                label7.Text = grossbuchstaben  ? "Ja" : "Nein";
            }

Jürgen

Nachtrag: Siehste, das ist das Problem. Du brauchst eine Abbruch-Bedingung innerhalb beider Schleifen, sobald der erste Treffer gelandet wurde, und das Label wird erst nach der Schleife gesetzt.

07.02.2010 - 20:08 Uhr

Das ist zwar alles möglich, aber überflüssig kompliziert. Das gilt vor allem für das Ursprungsverfahren:

Ein String besteht aus Chars, muss also nicht in ein char-Array konvertiert werden.
Ein Char.ToString ist dann erst recht unnötig.
Insbesondere gibt es die Char.IsUpper-Methode.

Jürgen

06.02.2010 - 17:36 Uhr

ist dies möglich/erlaubt?

Keine Ahnung. Aber vielleicht hilft dir ersatzweise dies: [Artikelserie] Den SharpDevelop Kern in eigenen Anwendungen verwenden oder [Tutorial] Einfaches Keyword-Highlighting

Gruß Jürgen

04.02.2010 - 08:58 Uhr

Bekommt so ein Steuerelement irgend ne ID die eindeutig ist und die ich Abfragen könnte?

Eindeutig nein. Du kannst nur Notlösungen vornehmen; welche davon passt, musst du selbst sehen. Du musst dich auch entscheiden, ob du die Anzeige-Daten dem DGV oder der DataTable zuordnen willst. Mir fallen folgende Verfahren ein:

  1. Benutze Tag und GUID: Wenn für das DGV noch Tag==null gilt, dann erzeuge eine GUID und weise diese Tag zu. Der Wert dieser Eigenschaft wird dann als ID zum Speichern verwendet.

  2. Theoretisch kann mit Handle gearbeitet werden. Aber beim nächsten Aufruf von Programm oder Formular ändert sich dieser Wert mit Sicherheit. Du kannst den allenfalls als Ersatz für eine ID verwenden über Tag (wie in 1).

  3. Am sichersten dürften eine String-Kombination von Anwendung + Assembly + Formular + DGV-Name sein. Das scheitert aber dann, wenn ein solches Formular mehrfach innerhalb einer Anwendung erstellt wird (wie in MDI-Anwendungen o.ä. möglich).

Gruß Jürgen

03.02.2010 - 17:02 Uhr

Hallo,

du könntest deine eigene config-Datei erstellen/mitliefern und als xml-Dokument einlesen. Aber besser ist es auf jeden Fall, die Einträge in die app.config zu schreiben. Das muss ja auch nur einmal bei der Installation erledigt werden, und dafür sind i.d.R. sowieso Admin-Rechte erforderlich.

Gruß Jürgen

03.02.2010 - 16:59 Uhr

Hallo Simon,

wenn du weißt, dass sich in dt1 nur int-Werte befinden (und bei DataTables weiß man das fast immer), geht es noch einfacher:

for (int k = 0; k < dt1.Rows.Count; k++)
{
     dt2.Rows[k]["Spaltenname"] = (int)dt1.Rows[k][0];
}

Bei dt1.Rows[0] ist wohl noch ein Schreibfehler übrig, nämlich Index k statt 0.

Gruß Jürgen

02.02.2010 - 19:26 Uhr

Hallo Daniel,

aus deinen Texten und Ausschnitten kann ich fast keinen Zusammenhang erkennen zwischen der Fehlermeldung und den verwendeten Indizes. Es sieht so aus, als wenn Columns[5] falsch wäre.

Kann es sein, dass du die Spalten ab 1 zählst? Das wäre unter C# und .NET völlig verkehrt; dort werden Indizes von Arrays und List usw. immer ab 0 gezählt.

Gruß Jürgen

Nachtrag: Wenn du schon so schön formulierst:

Ich hoffe das diese Frage dem Forum würdig ist

dann doch bitte richtig: Ich hoffe, dass diese Frage des Forums würdig ist

02.02.2010 - 17:40 Uhr

Hallo und willkommen,

für Klassen und Listen hat herbivore alles Wichtige gesagt.

Im Wikibook: Einführung in SQL habe ich es für Tabellen so formuliert:

Es ist üblicher, eine Tabelle im Singular zu bezeichnen.
* Es ist einfacher zu sagen: Ein Versicherungsvertrag hat diese Eigenschaften… Umständlicher wäre: Ein Datensatz der Tabelle Versicherungsverträge hat diese Eigenschaften…
* Vor allem beim Programmieren werden die Namen mit anderen Begriffen verknüpft; es käme dann etwas wie VertraegePositionenRow zustande – also die Positionen von Verträgen –, wo nur eine einzelne Zeile, nämlich eine Position eines Vertrags gemeint ist.
_ Kürzlich gab es in einem Programmiererforum (nämlich hier) eine kleine Diskussion über "Singular oder Plural". Dort wurde das als uraltes Streitthema bezeichnet, das zu heftigsten Auseinandersetzungen führen kann. Im Ergebnis sollte es eher als Geschmackssache angesehen werden._

Fazit: Auch hier Geschmackssache, kein Grund für Endlosdskussionen.

Gruß Jürgen

02.02.2010 - 08:56 Uhr

Hallo und willkommen,

nun ja, wenn du mit TableAdapter arbeitest, dann ist das weitgehend in Ordnung. Nur zwei kleine Änderungen möchte ich vorschlagen:

  1. Die Zeile mit AcceptChanges kann entfallen; das wird durch Update automatisch ausgeführt.
  2. [Tipp] Anfängerfehler == true / == false

Außerdem habe ich noch folgende Anmerkungen:
a. Bei sehr breiten Code-Auszügen mache bitte zusätzliche Zeilenumbrüche, das liest sich besser.
b. Es ist eher unpraktisch, jede Änderung sofort zu speichern. Üblich ist es, dass zuerst einiges bearbeitet wird und dann alle Änderungen "am Stück" zur Datenbank geschickt werden (auch wenn das in deinem Tutorial so vorgemacht wird).
c. Der TableAdapter erleichtert zwar am Anfang die Arbeit, aber die meisten Vorgänge werden versteckt, sodass du gar nicht mitbekommst, was alles passiert. Das verringert den Lernerfolg IMHO erheblich.

Gruß Jürgen

29.01.2010 - 19:21 Uhr

Verd..., hätte ich doch Frage hier und die Antwort von herbivore zuerst gelesen. Diese Doppel-Posts wie dort. Jürgen

[EDIT=herbivore]geschlossen wegen [Hinweis] Wie poste ich richtig? Punkt 2.2[/EDIT]

28.01.2010 - 13:06 Uhr

Kann ich die Fillmethode noch erweitern, indem ich den Befehl gebe, dass tatsächlich nur der entsprechende Datensatz angezeigt wird? Denn jetzt ist das Grid zwar anfangs leer, aber nach dem Klicken sehe ich wieder sämtliche 90 Datensätze. Ich muss das doch irgendwie (vllt anhand einer SQL Abfrage) einschränken können, oder?

Das ist genau der richtige Ansatz: Mit einem passenden SELECT kommen genau die gewünschten Datensätze (oder auch nur einer oder gar keiner).

Du stößt auf eines der Probleme, wenn man mit dem TableAdapter-Monster arbeitet: Da wird alles Mögliche versteckt, und keiner versteht, was da eigentlich abläuft. Mit dem Daten-Designer von VS kannst du auch andere SQL-Befehle vorbelegen (freilich habe ich keine Ahnung, ich arbeite nicht damit).

Zur Einführung in die DB-Verarbeitung unter NET siehe 🛈 Kap. 25 ff, außerdem siehe Einführung in SQL.

Gruß Jürgen

28.01.2010 - 12:59 Uhr

Hallo,

ohne Graphics geht es mit der TextRenderer.MeasureText-Methode. Der übliche Umrechnungsfaktor ist 96 (nicht 95).

Gruß Jürgen

PS. Laut Thema fragst du sowieso nach TextRenderer.MeasureText. Wieso hast du dann eigentlich zwischendurch auf Graphics umgeschaltet?

27.01.2010 - 14:49 Uhr
  1. Die MessageBox hat natürlich keine wirkliche Bedeutung.
  2. Die while-Schleife ist in dieser Situation eher Quatsch; denn bei der Übertragung in Labels kann nur ein Datensatz übernommen werden. Aber es ist abzufragen, ob überhaupt Werte geliefert wurden.
  3. Die Connection sollte in einen using-Block eingebaut werden wie im letzten Beitrag von [Artikel] Ressourcen schonen - Datenbanken richtig öffnen und schließen

Gruß Jürgen

26.01.2010 - 20:59 Uhr

Hallo herbivore,

es ist nur ein Absatz "Rundungen" innerhalb von: Teil II Elementarmathematik - 1. Näherungsrechnung - 1.1 Regeln für das Rechnen mit Näherungswerten. Es wird nur diese eine Art der Rundung beschrieben (ohne einen Namen dafür), allerdings mit Hinweis auf dabei auftretende Ungenauigkeiten und Fehler. Der Plural bezieht sich vermutlich darauf, dass es eine häufiger vorkommende Situation betrifft, aber nicht auf verschiedene Rundungsverfahren.

Mein o.g. Zitat umfasst etwa 3 Zeilen von insgesamt gut 9 Zeilen Text.

Jürgen

26.01.2010 - 19:16 Uhr

Bitte sehr:

... dabei wird die letzte stehenbleibende Ziffer um eine Einheit erhöht, wenn die erste wegfallende Ziffer größer als 4 ist. Besteht der wegzulassende Teil nur aus der einen Ziffer 5, dann rundet man so, dass die letzte stehenbleibende Ziffer eine gerade Zahl ergibt... Quelle: Bronstein, Taschenbuch der Mathematik, Leipzig 1969, S. 97 (Hervorhebung von mir)

Gruß Jürgen

PS. Meine Ausgabe ist zwar schon ein paar Monate älter, aber das zeigt eher, dass diese Regelung nicht neu ist, sondern eher als selbstverständlich angesehen wurde.

21.01.2010 - 15:15 Uhr

Hallo und willkommen,

ich schließe mich Jack und Bernd an und möchte ein bisschen ergänzen:

🛈 Kap.25 ff. hat eine kleine Einführung in die Kommunikation zwischen DB und Anwendung.

Du musst dir genaue Bezeichnungen angewöhnen; es gibt viele ähnlich lautende Klassen mit unterschiedlicher Bedeutung. Du schreibst von GridView, aber das gehört zu ASP.NET. Du meinst vermutlich immer DataGridView.

Solche Begriffe sind immer nützlich, um in :rtfm: selbst nachzuschlagen: Klasse - "Informationen zu..." und "Alle Member" mit kurzen Inhaltsangaben.

Den Grundsatz der DB-Verarbeitung unter NET hast du wohl schon kennengelernt; ich möchte ausdrücklich betonen, dass getrennt wird zwischen: Daten in der Datenbank - Daten im Arbeitsspeicher - Daten zur Anzeige.

Viel Erfolg! Jürgen

21.01.2010 - 09:40 Uhr

Hallo Simon,

das hängt davon ab, wie die Daten in die DataTable gelangen. Wenn es durch Rows.Add passiert, gilt immer DataRowState.Added - das ist die beste Voraussetzung (notfalls gibt es eine Methode SetAdded o.ä.). Dann kannst du einen DbDataAdapter erstellen, dazu einen **InsertCommand **(entweder automatisch aufgrund eines SelectCommand mit DbCommandBuilder oder manuell, was bei deiner Vorarbeit wahrscheinlich einfacher ist) und dann DbDataAdapter.Update ausführen. Die Schleife mit der Zuordnung der Parameter und Transaction geht dann sozusagen automatisch.

Ein Mini-Beispiel für den InsertCommand ist auch in [Artikelserie] Parameter von SQL Befehlen enthalten.

Gruß Jürgen

20.01.2010 - 16:03 Uhr

Hallo,

Florians Antwort kann ich nur unterstreichen.

Zu XML ist ein Tutorial fast überflüssig. Lies dich in 🛈 DataSet/DataTable ein und benutze **ReadXml **bzw. WriteXml, das ist alles. In diesem Befehl kann man immer nur die Datei als Ganzes lesen bzw. schreiben, aber nicht einzelne Datensätze.

Gruß Jürgen

20.01.2010 - 12:59 Uhr

... Man das auch besteimmt direkt in einem Rutsch in die DB schreiben.
Da weiß ich aber grade nicht wie.

Das geht eigentlich nur dann, wenn die Daten schon in einer sauberen Struktur vorhanden sind wie einer DataTable. Wenn sie aber aus einem String-Array kommen (igitt, aber wer weiß, wie das entstanden ist), dann ist dieses Vorgehen akzeptabel; die innere Schleife ordnet schließlich das "innere" Array den Spalten-Parametern zu und ist deswegen richtig.

Jürgen

20.01.2010 - 12:50 Uhr

Wenn du mit dem TableAdapter arbeitest, dann unbedingt! Ich habe aber schon davon gelesen, dass das nicht immer auf Anhieb funktioniert, weil irgendein Schalter übersehen wird.

Gruß Jürgen

18.01.2010 - 20:08 Uhr

Wenn Du es einfach brauchst, kannst Du auch ein Hochkomma ...

Verd... wozu gibt es die vernünftigen Lösungen, wenn dann doch ein Blödmann Mensch kommt und einen unsinnigen Ersatz vorschlägt. Eine Beleidigung ist sonst nicht meine Sache; aber wenn 3 Mal die richtige Lösung genannt wird und dann doch noch eine dumme Lösung kommt, platzt auch mir der Kragen.

Unbedingt **Parameter **benutzen, alles andere ist Quatsch und führt eher früher als später zu gravierenden Problemen!

Jürgen

18.01.2010 - 14:33 Uhr

Das Verwenden von Parametern ist wirklich sinnvoll und hat noch viele weitere Vorteile. ... Also: Lieber parametrisierte SQL-Statements verwenden

Die Artikel gibt es im Forum, damit nicht immer alles neu wiederholt werden muss. So gut wie alle deine Gesichtspunkte stehen in der bereits genannten [Artikelserie] Parameter von SQL Befehlen. Jürgen

18.01.2010 - 09:50 Uhr

...Die Random-Instanz darf für ordnungsgemäße Nutzung nur einmal erzeugt werden...
Nein, keinesfalls.

Grrh. Ich hatte sehr gezögert, bevor ich das "darf" geschrieben habe. Gemeint war natürlich: "innerhalb eines Zusammenhangs". Ich hatte mich auch nur deshalb gemeldet, weil es in der ersten Antwort hieß:

Besser wäre hier im Button2Click die Random-Class nur einmal zu erzeugen...

In diesem Zusammenhang war es (wie die folgenden Versuche zeigten) nicht nur besser, sondern notwendig, diese eine Instanz weiterhin zu benutzen.

Aber, es spricht nichts dagegen so viele Random Objekte zu erzeugen wie man möchte, man muss halt nur um dieses Verhalten wissen.

Nicht nur "wie man möchte", sondern "wie man braucht". In der Mehrzahl der (Anfänger-) Fälle braucht man eben genau eine Instanz.

Gruß Jürgen

17.01.2010 - 19:00 Uhr

Besser wäre hier im Button2Click die Random-Class nur einmal zu erzeugen und also immer wieder die selbe Random-Instanz zu übergeben und zu nutzen.

Nicht nur besser, sondern das ist der entscheidende Punkt. Die Random-Instanz darf für ordnungsgemäße Nutzung nur einmal erzeugt werden, z.B. im Konstruktor der Klasse. Jürgen

17.01.2010 - 15:16 Uhr

Hallo,

dein Denkfehler ist, dass du Zeilen und Spalten verwechselst: In der ersten Zeile ist i der Zeilenindex, in der zweiten Zeile benutzt du diesen Werte als Spaltenindex.

Wenn du überhaupt so vorgehen willst, musst du es etwa so machen:

for( int x = 0; x < Columns.Count; x++ )
   TextBoxes[x].Text = CurrentRow.Cells[x]

Das ist Pseudo-Code, weil ich viele Details weggelassen habe und die TextBoxen in einem eigenen Array stecken. Ich hoffe aber, das Prinzip wird deutlich.

Siehe auch [FAQ] Variablennamen zur Laufzeit zusammensetzen; das ist kein gutes Verfahren, hilft aber in diesem Fall vielleicht.

Jürgen

14.01.2010 - 19:10 Uhr

Das dann aber per PN!

Nein, so nicht! (Und doppelt fragen - im Forum und mit zwei PNs? 8o )

Wobei deine eingesetzte Lösung mit Firebird wohl auch nicht die schnellste sein dürfte? 😉

Das verstehe ich überhaupt nicht. Welche Lösung habe ich mit Firebird erwähnt? Ich benutze den FbProvider, und das funktioniert.

Jürgen

14.01.2010 - 18:11 Uhr

Auch hier fehlt mir eine Anleitung wie ich das am besten mache. Bezüglich Daten abschicken, etc.

Wie bei jeder anderen DB-Anbindung auch. Wenn im 🛈 Kap.25 ff. von Sql-Klassen gesprochen wird, musst du eben MySql-Klassen verwenden. Wenn im Forum von Db-Klassen oder einem DbProvider gesprochen wird, musst du das ebenfalls in "MySql" übersetzen. Eine spezielle Anleitung ist überflüssig.

Bei Parametern oder SQL-Befehlen musst du die speziellen Vorgaben beachten, siehe z.B. [Artikelserie] Parameter von SQL Befehlen oder MySql-Referenz

Gruß Jürgen

PS. Oledb solltest du schleunigst wegschmeißen. Das führt häufig zu unerklärlichen Fehlern. Wenn du mehrere DBMS bedienen willst, dann kümmere dich lieber um O/R-Mapper.

14.01.2010 - 12:46 Uhr

wobei ich mir das richtig schwierig vorstelle, sowas zu automatisieren, weil es ja durchaus ein oder sogar mehrere ein längere Texte an verschiedenen Stellen des Artikels sein können, die möglicherweise in anderen Versionen wieder geändert oder ergänzt wurden. Oder meinst du, dass dann die Admins direkt auf der Datenbank hantieren?

Das nehme ich an, weil es sich um eine Ausnahmesituation handelt, und zwar nicht die Admins, sondern die nächsthöhere Stufe (die heißen wohl Bürokraten).

Übrigens wird bei jeder noch so kleinen Änderung immer die komplette Seite neu gespeichert. Insofern geht es technisch durchaus.

ich habe irgendwo schon mal einen Hinweis gelesen
Meinst du, du findest die Stelle noch?

Nein, bestimmt nicht. Das ist schon ein paar Monate her; ich weiß noch nicht einmal, ob das in der Wikipedia oder in Wikibooks war.

... hat es ja auch andere Nachteile zum Beispiel bezüglich des Vertrauens, wenn die Versionshistorie nachträglich geändert werden kann. Insofern kann man dieses Thema ja sehr kontrovers sehen.

In der Tat. Deshalb wäre es die absolute Ausnahme. Die Admins prüfen schließlich jeden einzelnen Beitrag und jede kleine Änderung, damit derartige Probleme vermieden werden.

Gruß Jürgen

14.01.2010 - 11:38 Uhr

Hallo herbivore,

die Möglichkeit, eine Version vollständig zu entfernen, sollte es geben. Ich glaube, ich habe irgendwo schon mal einen Hinweis gelesen, dass das gemacht worden ist (aber keine Ahnung wo).

Die "normalen" Administratoren haben keine solchen Rechte. (Ich bin bisher nur Autor, wurde aber schon aufgefordert, unter Wikibooks als Admin tätig zu werden.)

Gruß Jürgen

13.01.2010 - 09:52 Uhr

Hallo,

bei deiner Beschreibung und deinem Code komme ich völlig durcheinander. Das ist dir vielleicht auch passiert.

Weder der Code noch die Beschreibung hat etwas mit DataGridView zu tun (jedenfalls fast nichts); dieser Begriff hat also auch nichts in der Überschrift zu suchen. Also ändere über deinen (ersten) Beitrag die Überschrift.

Ein GridView ist etwas ganz anderes; diesen Begriff darfst du deshalb auch nicht verwenden. Lediglich "Grid" als vereinfachte Bezeichnung ist zulässig.

Ich verstehe auch gar nicht, was Artikel, ArtNr, Bestand mit Vorname, Nachname, Geburtsdatum zu tun haben.

Niemand kennt die Struktur deiner Datenbank-Klasse oder deiner MySql-Datenbank. Wie soll man dazu etwas sagen?

Es kommt mir reichlich mysteriös vor, dass drei String-Variablen aus der "datenbank" geholt werden, die Werte in drei String-Arrays aufgeteilt und dann in eine DataTable übertragen werden. Warum verwendest du nicht das Standard-Verfahren per DbDataAdapter.Fill("Artikel"), siehe 🛈 Kap.25 ff.

Klassennamen gehören übrigens großgeschrieben, siehe .NET Richtlinien für Namen.

Zur konkreten Frage nach dem Ende der for-Schleife: Zum einen gibt es foreach. Zum andern gibt es :rtfm:, wo zur Array-Klasse die entsprechende Information zu finden ist.

Aber wie gesagt: Sortiere erst einmal deine Gedanken, plane vernünftig und fang dann nochmal an.

Gruß Jürgen

10.01.2010 - 10:46 Uhr

Hallo Lars,

eine Datenbank-VIEW ist doch nichts anderes als eine (in der DB fest gespeicherte) SELECT-Abfrage. Diese kannst du doch mit wie vielen JOINs auch immer per DbDataAdapter.Fill in eine DataTable holen und anzeigen. Nur einfaches Speichern geht auf diesem Weg nicht.

Für das Speichern in einer lokalen Access-Datei sehe ich keinen Grund, sofern alles im Arbeitsspeicher ablaufen kann.

Was mit NET 2.0 (nämlich ohne Linq) nicht geht, das ist eine DataView aus mehreren DataTables eines DataSet zu erstellen.

Gruß Jürgen

07.01.2010 - 09:43 Uhr

... Diese zu verwenden ist objektorientierterer Stil als die eher prozedurale Convert-Klasse.

Danke für diese Begründung! Ich wurde vor ein paar Tagen gefragt, warum double.ToString besser ist als Convert.ToString(double) und konnte es nur "nach Gefühl" beantworten (denn beides ist ja gleich implementiert). Gruß Jürgen

07.01.2010 - 09:36 Uhr

Auch wenn kleines Eichhörnchen die korrekte Antwort auf deine Frage gegeben hat, ist in der Praxis Convert selten sinnvoll. Um einen String zu erhalten, gibt es wie für jede Klasse die ToString-Methode. Um den Wert zu erhalten, gibt es **TryParse **bzw. (wenn Fehler unwahrscheinlich sind oder TryParse wie bei Enum nicht vorhanden ist) Parse.

Gruß Jürgen

06.01.2010 - 18:59 Uhr

Schau in :rtfm: BrowsableAttribute-Klasse. Jürgen

PS. Siehe auch Standard

06.01.2010 - 09:42 Uhr

Hallo,

wenn herbivore nicht konkret werden will, hat er in der Regel recht. Ausnahmsweise will ich dennoch ein paar Hinweise geben:

* Da in den anderen ComboBoxen immer alle Werte vorhanden sein sollen, brauchst du eine vollständige originale Liste, z.B. eine List<T>.
* Wenn eine Items-List geändert werden soll, wird die komplette Liste kopiert, das unerwünschte Element entfernt und der betreffenden ComboBox zugewiesen.
* Das kann in einer gemeinsamen Methode erledigt werden (Parameter: Ziel-ComboBox, unerwünschtes Element).
* Wenn eine Auswahl aus einer ComboBox etwas auslösen soll, kommen die SelectedXxxChanged-Ereignisse infrage.

Das muss aber wirklich reichen, Nachfragen bitte erst mit konkreten Versuchen. Jürgen

06.01.2010 - 09:26 Uhr

fast jedes objekt bietet dir eine .ToString() Methode an,

Kleine Korrektur: Jedes Objekt hat diese Methode; das ist Grundlage für object, und alle Klassen sind von object abgeleitet.

Außerdem ist ein **String **auch ein char-Array. Man kann deshalb auch die Vergleiche direkt mit den Zeichen durchführen:

            char buchst = 'o';   // geänderte Deklaration
            int anzahl = 0;

            if (wort.IndexOf(buchst) >= 0)
            {
                foreach (char zeichen in wort)
                {
                    if (zeichen == buchst) anzahl++;
                }
            }

Gruß Jürgen

05.01.2010 - 19:04 Uhr

Das deutet darauf hin, dass der TableAdapter aus irgendeinem Grund keinen DeleteCommand erzeugt hat. Unter welchen Umständen das geschehen kann, weiß ich nicht; ich benutze diese Konstruktion nicht.

Vielleicht wirst du in 🛈 Kap.30.5 fündig. Jürgen

05.01.2010 - 17:45 Uhr

Natürlich. Aber der Provider will beim Ausführen eines DbCommands wissen, was er zu übergeben hat; dazu will er wissen, von welchem Datentyp die Werte sind, die in den Parametern stecken, und als welcher DB-Typ sie ankommen sollen. Das wird durch die richtige Add-Variante gesteuert. (Es gibt noch andere Varianten - schau dir einmal die vielen verschiedenen Parameter-Konstruktoren an).

Gruß Jürgen

05.01.2010 - 16:16 Uhr

Ein TableAdapter ist unglaublich unübersichtlich. Ernsthafte Programmierer lehnen sie schon wegen der Monstergröße ab; außerdem verstecken sie viele nützliche Informationen.

Du musst nach **schuelerTableAdapter **vor allem im Zusammenhang mit **DeleteCommand **suchen.

Jürgen

05.01.2010 - 16:12 Uhr

Gut, ich habe noch mal was geändert:

// DB-Connection aufbauen

So ist es schön! 👍

Dann noch einmal zu #1:
Mich stört, dass ich hier den Typ explizit angebe. Wenn ich den mal ändere, muss ich auch an diese Stelle denken. Daher würde ich das gern anders machen.

Ich sagte schon: Wenn du es nicht mit AddWithValue machst - und das passt bei einer Schleife nicht -, dann muss der Typ angegeben werden.

Die Verwendung von SQLiteDbType wird bei mir als "im aktuellen Kontext nicht vorhanden" angemeckert. Welche using-Anweisung müsste ich da ergänzen?

Nix. Es geht um die spezielle Ableitung von DbType (das ist die Basisklasse) für deinen Provider. Wie die Klasse genau heißt, musst du nachschlagen; aber sie liegt mit Sicherheit im selben Namespace wie die anderen SQLite-Klassen.

Gruß Jürgen

05.01.2010 - 16:02 Uhr

Hallo,

zuerst bitte ich dich, immer die korrekte Bezeichnung zu verwenden. Bitte korrigiere das in deinem ersten Beitrag (Überschrift und Text): Du arbeitest mit einem DataGridView - die eine Bezeichnung gibt es nicht, die andere bedeutet etwas anderes. Falsche Bezeichnung bringen die Forumssuche und damit die Forumsnutzer durcheinander.

Die Lösung für dein Problem liegt in einer Nachschlagetabelle: Erstelle eine zweite **DataTable **mit der Zuordnung von Werten/Anzeigetext, dazu eine **DataRelation **(analog zu einem ForeignKey) und benutze dafür DataGridView: Master/Detail über ComboBox .

Gruß Jürgen