Laden...
-
-Hades- myCSharp.de - Member
Deutschland NRW Dabei seit 05.11.2007 171 Beiträge
Benutzerbeschreibung

Forenbeiträge von -Hades- Ingesamt 171 Beiträge

22.04.2016 - 18:43 Uhr

Ja MVC ist klar, mir ging es um die empfangenen Daten selber. Diese liegen ja im Moment bei mir in Form von datasets vor. Mit dem neuen Design würden das ja JSON-formatierte Daten sein wenn ichs richtig verstanden habe. Werden diese Daten auch direkt als Datasource von beispielsweise datagrids verstanden und können direkt gebunden werden oder muss ich da dan noch selber Hand anlegen und dann nochmal Strukturen draus aufbauen?

Edit: Und sorry, ich werde gewiss weit mehr als nur eine Stunde investieren aber ich finde das hier eine sehr gute Möglichkeit um ein Gefühl für den Umfang der Portierung und generell der Möglichkeiten zu bekommen.

22.04.2016 - 17:57 Uhr

Hmm ok und gibt es auch Tools die die Strukturen die zwischen Service und WPF-Anwendung ausgetauscht werden in Klassen umwandelt? Also wenn du sagst ich nutze den ORMapper im Service, gut kann ich mir vorstellen. Dann werden die Daten in JSON-Format umgewandelt, warum macht man das? Weil es ein Standard ist?? Und wie gesagt, wie gehe ich dann mit den XML-Daten in der WPF-Anwendung um, sprich ich möchte ja diese Daten an Datagrids usw. binden und natürlich auch generierte Methoden nutzen können um zum Beispiel relationell bezogene Daten zu einem Objekt (Buchungssätze zu einer Rechnung) abrufen zu können. Halt all das was der ORMapper sonst generiert hätte.

22.04.2016 - 17:35 Uhr

Ah interessant. Das heißt der Service würde direkt auf der Azure-Maschine laufen und mittels Protocol-Buffer mit der WPF-Anwendung kommunizieren? Und dieser buffer wäre sowas wie ein Stream an den ich beispielsweise eine neue Klasseninstanz schicke (sagen wir mal eine neu aufgenommene Eingangsrechnung eines Unternehmenes) und der service schickt das an das DBMS? Und welche Rolle spielen da dann die OR-Mapper, also wie kann ich mir das mit der Datenstruktur zwischen DBMS, Service und WPF-Anwendung vorstellen?

Edit: Ja die Übersetzung in LINQ-ausdrücke finde ich auch nicht gut, vor allem weil es viel schwerer zu lesen ist.

22.04.2016 - 17:25 Uhr

Hmm ich verstehe nicht was du meinst. Natürlich nutze ich den generierten Code, dafür wurde er ja generiert und natürlich verlasse ich mich darauf das er funktioniert. Ich habe die Klassen höchstens an einigen Stellen erweitert, um einfach mehr Comfort bei den Abfragen zu haben.

Ich denke nicht das wir uns verlaufen haben. Die Anwendung funktioniert und ist auch bei Unternehmen im Einsatz. Das mit dem Laden der Daten auf den lokalen Rechner ist natürlich extrem unschön aber ich habe ja gesagt warum ich das getan habe. Ich bin froh über jeden Kommentar, wie würde ich das Laden der Daten denn anders behandeln können ohne das die Anwendung spürbar bei jeder Ansicht auf den Server warten muss?

Es geht auch nicht darum etwas zu reparieren. Ich habe eine zugrundeliegende MySQL-Datenbank, mehr erstmal nicht. Die Controls muss ich ja ohnehin neu erstellen und ich möchte einen neuen OR-Mapper nutzen. Das kommt einer Neuentwicklung ja schon recht nahe. Einzig die Controllerklassen können natürlich bleiben.

Edit: Der Resharper hat natürlich keinen Code generiert, er dient nur als intelligentes Auto-Vervollständigungstool beim Entwickeln.

22.04.2016 - 17:04 Uhr

Danke soweit für die Antworten,

mit der GUI ist ja schjonmal super!

Also mit dem ORM ist etwas schwierig für mich zu spezifizieren auf was es ankommt. Ich kannte zum Zeitpunkt der Erstellung nichts anderes und es funktionierte halt. Was ich sagen kann ist, das die Datenbank halt recht groß ist. Der erzeugte Code z.B. ist dermaßen lang, dass es in der Praxis zu heftigen Performance-Einbußen kommt wenn ich beispielsweise den Resharper nutze. Selbst wenn ich die betreffenden Dateien aus dem Resharper-Scan rausnehme ist es schwer flüssig zu arbeiten da er die Dateien halt doch durchsucht wenn ich auf den Typ einer Zeile oder dergleichen zugreife. Aber höchstwahrscheinlich wird da auch kein OR-Mapper abhilfe schaffen oder?

Vielleicht noch etwas zur Vorgehensweise meiner Anwendung. Die Datenbanken sind im Moment auf Microsoft Azure-Maschinen abgelegt. Beim Start der Anwendung lade ich fast alles lokal in die Datasets um darauf dann zu arbeiten und jeweils neue Daten direkt zu committen. Dieses naive Vorgehen habe ich aus Geschwindigkeitsgründen gewählt. Permanent vom Server zu laden ist einfach zu langsam da ich viele Ansichten habe die fast alle Prozesse eines Unternehmens anzeigen müssen, beispielsweise alle Ausgangsrechnungen eines Jahres.
Vielleicht helfen die Beschreibungen noch etwas für die Wahl eines OR-Mapper oder vielleicht weiß jemand generell bessere Vorgehensweisen mit meinen Daten umzugehen. Im Moment ist die Anwendung auch nicht mehrplatzfähig um Inkosistenzen zu vermeiden, das muss in Zukunft auch geändert werden.

22.04.2016 - 16:24 Uhr

verwendetes Datenbanksystem: MySQL

Hallo zusammen,

ich möchte in der nächsten Zeit ein ERP-System modernisieren. Zur Zeit verwende ich MySQL-Datenbanken (mit der MySQL-Workbench erstellt), welche ich in strong typed datasets übersetzen lasse, zusammen mit Winforms. Die Datenbank besteht aus über 100 Tabellen und ist mittlerweile relativ komplex.
Die grafische Ansicht lässt leider etwas zu wünschen übrig und deshalb möchte ich anfangen das ganze zu WPF zu "portieren". Im Zuge dessen wäre es wahrscheinlich ratsam die strong typed datasets durch etwas zeitgemäßeres zu ersetzen.
Die Frage ist jetzt welche Technologien würdet ihr mir empfehlen? Klar, zu WPF scheint es ja keine Alternative zu geben (gibt es eigentlich sowas wie einen open source store für vorgefertigte WPF-Elemente die schon schick aussehen, vor allem um datengebundene elemente anzuzeigen?) aber vor allem für die Daten wäre es wichtig zu wissen was es gibt und was eurer Meinung nach Sinn macht. Also vor allem welche OR-Mapper taugen was und was sind die Schwachstellen. Die meisten Artikel die ich so gefunden habe sind höchstwahrscheinlich recht gut, allerdings auch schon sehr alt und deshalb die Frage hier nochmal um ganz aktuelle Erfahrungen zu hören.

Beste Grüße
-Hades-

25.02.2014 - 15:55 Uhr

Das wäre durchaus denkbar und ist wahrscheinlich eine saubere Lösung.

Gruß
-Hades-

25.02.2014 - 15:22 Uhr

Hehe,

ja das geht natürlich... Ich schaue selbst noch einmal ob das Verhalten nicht zu ändern ist. Die Items kommen direkt aus einer Datenbank und werden per Datasource gebunden. Ich möchte solche Sachen an sich nicht mit in die Datenbank aufnehmen und vor allem müsste ich das dann an sehr vielen Stellen machen (über 20 Tabellen).
Vielleicht kann ich, wenn auf die Box geklickt wird, ja den Text der Box löschen oder so, ich schaue mal.
Vielen Dank soweit für die Hilfe!

Gruß
-Hades-

25.02.2014 - 12:44 Uhr

Hmm ok dann hattest du mich doch verstanden. Allerdings löst ein Eintrag "Keine Auswahl" oder dergleichen nicht unbedingt mein Problem. In der Tat ist es so, dass es bereits Einträge gibt die "Kein Wert" darstellen aber auch diese sollen oder vielmehr müssen vom Anwender bewusst eingegeben werden, weshalb es an der Stelle wichtig ist das der Benutzer sozusagen gezwungen wird etwas auszuwählen, da der "Kein Wert"-Eintrag halt auch den Programmfluss entscheidend beeinflusst.
Im Prinzip wollte ich die betreffende Spalte sogar farbig hinterlegen solange der Anwender nichts explizit ausgewählt hat.
Es würde halt schon reichen wenn nichts in das Auswahlfeld geschrieben wird solnage kein Item explizit ausgewählt wurde, so dass der Anwender nicht verwundert ist das die Box wieder geleert wird wenn die Box den Fokus verliert.

25.02.2014 - 11:21 Uhr

Hallo herbivore,

nein da hast du mich missverstanden. Es ist bei mir so, dass zunächst kein Wert in der Combobox steht, das ist auch gut so. Wenn jetzt der Anwender auf die Box klickt, so dass die Drop-Down-Liste angezeigt wird, steht in der Combobox bereits der Name des ersten Items der Dropdown-Liste. Wenn jetzt kein Item der Dropdown-Liste ausgewählt wird, sondern z.B. ganz woanders auf die Form geklickt wird, verschwindet der Name in der Combobox aber wieder, obwohl der Anwender dachte es sei bereits der erste Eintrag genommen worden. Dieses Verhalten ist sehr unintuitiv.
Erst wenn mit der Maus wirklich nochmal explizit ein Item der Dropdown-Liste angeklickt wird, behält die Combobox diesen Wert auch nachdem sie den Fokus verliert.

Ich hoffe so war es verständlicher.

Gruß
-Hades-

24.02.2014 - 19:53 Uhr

Hallo,

ich habe in meinen Datagridviews viele ComboBoxen. Standardmäßig haben diese keinen Default-Wert, sind also nicht gefüllt. Die Datasource ist allerdings gesetzt. Wenn man jetzt auf die Combobox klickt, wird der erste Eintrag aus der Datasource direkt in die Combobox geschrieben, als wenn man den Eintrag ausgewählt hätte.
Wenn jetzt allerdings keiner der Einträge direkt ausgewählt wird, klappt die Combobox wieder zu und der anscheinend ausgewählte Wert verschwindet und die Box ist wieder leer.

Weiß jemand wie man dieses Verhalten abändern kann, so dass entweder kein Wert in die Box geschrieben solange man nichts explizit ausgewählt hat oder das der angezeigte Wert dann auch wirklich ausgewählt ist?

Gruß
-Hades-

29.01.2014 - 17:36 Uhr

Hallo,

das Thema ist etwas sehr schwammig, deshlab versuche ich es so gut wie möglich zu erklären.
Ich möchte in einem Datagridview einen Wert darstellen. Die Datasource für das Datagridview enthält allerdings nur die Referenz-ID für den eigentlichen Wert. In dem Fall kann ich ja die Column zu einer DatagridViewComboBox machen und per Display- und Valuemember festlegen, welches Property ich aus der referenzierten Tabelle anzeigen möchte.
Soweit so gut.
Was aber, wenn der eigentliche Wert noch einmal oder mehrmal referenziert ist? Also Tabelle A enthält die ID für B und B die ID für C. In C steht der Wert den ich anzeigen möchte. Kann das so über den Designer auch erreicht werden?
Ich kann die Sachen natürlich selbst zusammenbauen aber es wäre schöner wenn das so direkt gehen würde.

Ich hoffe das ist verständlich formuliert.

Gruß
-Hades-

15.01.2014 - 19:55 Uhr

Hallo FZelle,

ja ich arbeite unter Windows. Ich habe schon den Windows-Treiber zu nutzen. Der Drucker wird auch erkannt aber wenn ich versuche per PrintDocument was zu schicken wird nichts gedruckt.

15.01.2014 - 18:13 Uhr

Hallo,

ich bin gerade dabei einen Bondrucker anzusteuern. Das Gebiet ist mir bis jetzt völlig neu und nach mittlerweile 6 Stunden try and error suche ich lieber Hilfe von erfahrenen Leuten.

Also erstmal zum Drucker:

Es ist der Bondrucker BP-002 von Birch und wir über USB angeschlossen.

Nach langem googlen bin ich der Meinung das die Nutzung von POS for .Net wohl das einfachste wäre den Drucker zu bedienen. Allerdings benötigt man ja anscheinend spezielle OPOS-Treiber. Einmal ein Service Object und einmal ein Control Object. Nichts davon habe ich auf der Seite von Birch gefunden, zumindest denke ich das es da nichts verwertbares gibt. Auf der Seite ist ganz unten ein Download-Link zu OPOS und darin waren ocx-Dateien. Ich habe per regsvr32 die OPOSPOSPRINTER.ocx zur Registrierung hinzugefügt aber das hat auch nichts verändert denke ich.

Ich habe dann von EPSON auch OPOS-Treiber installiert und diese werden dann auch in der POS for .Net Sample Applikation aufgelistet als PosPrinter.

Wie dem auch sei, meine Frage ist jetzt wie ich am besten vorgehe um mit meinem Drucker zu drucken. So einen OPOS-Treiber selbst schreiben wollte und könnte ich nicht. Habe ich vielleicht bei der Installation der Birch-Treiber was falsch gemacht oder kann ich vielleicht sogar die EPSON-Treiber nutzen? Oder sollte ich von OPOS Abstand nehmen und den Drucker anders ansteuern und wenn ja wie muss ich da vorgehen?

Ich hoffe jemand hat vielleicht schonmal diesen Bondrucker zum drucken gebracht. 😃

Gruß
-Hades-

14.01.2014 - 12:57 Uhr

Habe es jetzt gelöst. Habe Reflection genutzt und muss dadurch keine Liste oder dergleichen aufbauen. Klappt perfekt und ist n 3-Zeiler 😉

14.01.2014 - 09:40 Uhr

Hallo Coffeebean,

daran hatte ich auch gedacht. Du meinst anstatt Dataset bestimmt TableAdapter?

Das heißt ich würde eine partial class für den TableAdapterManager anlegen und darin manuell eine Liste der TableAdapter anlegen und diese dann durchiterieren und dessen Namen parsen.
Dabei gibt es nun mehrere Probleme. Erstens ist es aufwendig die Liste überhaupt erst zu erstellen, da das bei ca. einhundert Tabellen aufwendig ist und manuell immer geupdated werden müsste. Des Weiteren ist die Oberklasse der TableAdapter Component, welche keine Update-Methode bereitstellen. Das müsste also irgendwie durch eine Abfrage ob es ein Update() gibt und dessen Aufruf umgangen werden. Und ich prüfe mit Sicherheit nicht mit

if (TableAdapter is TableAdapterForTableX)

jeden einzelnen durch.

Falls ich dich falsch verstanden habe und du meintest doch was anderes so schreib bitte noch einmal zurück. Ich möchte allerdings schon die Insert-, Update- und Delete-Commands der erzeugten TableAdapter nutzen.

Gruß
-Hades-

14.01.2014 - 01:42 Uhr

verwendetes Datenbanksystem: MySQL

Hallo,

ich benutze typisierte Datasets und habe mittlerweile sehr viele Tabellen.
Ich würde gerne eine Methode schreiben, mit der ich lediglich den Namen einer Tabelle oder die DataTable angebe und der passende TableAdapter ruft Update() für diese Tabelle auf.

Das Problem ist, das der TableAdapterManager keine Liste der einzelnen TableAdapter hält, sondern alle Adapter als Properties beinhaltet, ich kann also nicht ohne weiteres durch alle iterieren um dne richtigen zu finden. Des Weiteren ist in den TableAdapter-Instanzen nicht der zugehörige Tabellenname gespeichert oder dergleichen. Lediglich der Name des TableAdapter selber könnte geparst werden um so zu checken ob er zum Tabellennamen passt.
Das erscheint mir allerdings nicht als die beste Lösung.
Ein UpdateAll() kommt für mich nicht immer in Frage da dadurch an einigen Stellen im Programm Probleme auftreten.

Ich hoffe jemand hat eine elegante Lösung für dieses Problem, da das wirklich sehr nützlich wäre. Meine Commit-Methode zeigt beispielsweise eine Art Busy-Screen an und friert die GUI ein und es wäre extrem ärgerlich wenn ich die Methoden immer einzeln aufrufen muss, nur weil es keine gescheite Möglichkeit gibt den TableAdapterManager zu veranlassen die Änderungen einer spezifischen Tabelle in die DB zu schreiben.

So ist es bis jetzt:

TableAdapterManager.TableAdapter.Update(dataset.DataTable)

Ich möchte:

TableAdapterManager.Update(dataset.DataTable)

oder

TableAdapterManager.Update("tableName")

Gruß
-Hades-

19.12.2013 - 10:39 Uhr

Hallo Programmierhans,

danke für die Idee. Kann ich den TableAdapter denn erweitern? Denn der eigentliche Code wird ja generiert, da ich ein typisiertes Dataset benutze. Diesen möchte ich nicht abändern, da sich im Laufe der Zeit immer mal wieder was an der Datenbank ändert.

Ich nehme die Blobs mal raus und teste es dann erneut.
Default-Werte habe ich nicht gesetzt.

17.12.2013 - 23:59 Uhr

Also ich habe eine Spalte mit Zeitstempeln, allerdings gibt es keine Zeile mit leerem Zeitstempel...
Kann es vielleicht an der Formatierung des DateTime liegen?
Andere Spalten sind Booleans und z.B. ein Byte-Array als Blob, welches auch nicht leer ist.
Einzig einige Boolean-Spalten werden nicht von mir gesetzt und sind demnach dann DBNull.

17.12.2013 - 20:32 Uhr

Also außer einem Primary Key mit AutoIncrement kann doch eigentlich nichts die Daten der Zeile ändern oder? Ich schreibe ja alle Daten selbst in die Zeile und da gibts auch keinen anderen Benutzer der auf die Datenbank zugreift.

Es sei denn, dass MySQL die Daten der Zeile eigenständig beim Einfügen verändert, das wäre dann natürlich das dümmste was passieren kann, dann würde ich um ein erneutes Fill ja gar nicht herum kommen, das kanns ja nicht sein.

17.12.2013 - 20:30 Uhr

Hey FZelle,

warum unsäglich? Sollte ich anstatt des TableAdapterManager etwas anderes benutzen?
Wie kann ich denn da sehen was da schief läuft?

17.12.2013 - 16:35 Uhr

verwendetes Datenbanksystem: MySQL

Hallo,

ich bekomme des öfteren eine Parallelitätsverletzung wenn ich eine Zeile per Delete lösche und dann per TableAdapterManager ein Update durchführe.

Zu dem Thema habe ich viele Threads gefunden, allerdings beziehen sich diese meist darauf, dass die Primärschlüssel nicht aktualisiert sind im Dataset oder dergleichen.
Der Primärschlüssel wird von mir selbst als GUID vergeben.
Wenn ich eine Zeile erstelle, diese meinem Dataset hinzufüge und dann durch den TableAdapterManager in die Datenbank schrieben lasse ist alles ok. Danach rufe ich Dataset.AcceptChanges auf. Wenn ich dann allerdings die Zeile per Delete() lösche und dann wieder das Update aufrufe bekomme ich die Parallelitätsverletzung.
Wenn ich zwischen dem Einfügen und Löschen das Programm neu starte und das Dataset neu fülle klappt es. Also es sieht genau wie das Problem mit den Primärschlüsseln aus aber die erstelle ich ja selbst und ändere sie auch nicht.
Die betroffene Zeile hat beinhaltet Fremdschlüssel, allerdings bleiben die referenzierten Zeilen alle erhalten und sind auch schon in der Datenbank.

Ich hoffe jemand weiß da einen Rat was ich überprüfen kann.

Gruß
-Hades-

25.11.2013 - 14:09 Uhr

Ok es klappt jetzt wieder,

die App.config wurde gelöscht. Ich konnte den Inhalt zum Glück durchs svn wieder herstellen.

Danke nochmal für die Hilfe.

Gruß
-Hades-

25.11.2013 - 10:58 Uhr

Also in dem Projekt in dem ich die Service Reference nutzen möchte ist eine app.config. Ob diese "passt" kann ich nicht beurteilen aber in dem WCF-Projekt selber ist keine app.config. VS sagt mir ja das in der gesamten Projektmappe kein Dienstverweis gefunden werden kann, deshalb denke ich, dass in dem WCF-Projekt selbst etwas fehlt oder abgeändert werden muss.

25.11.2013 - 09:39 Uhr

Ah okay,

ich glaube da kommen wir der Sache schon näher. Es gibt nämlich gar keine svc Datei bei mir. Ich habe die Ordner der WCF-Library durchgeguckt (bin, Debug etc.) und nichts gefunden. Wo sollte die denn liegen und was könnte passiert sein das die nicht mehr generiert wird?

24.11.2013 - 23:22 Uhr

Die .suo zu löschen hat leider auch nichts gebracht...

24.11.2013 - 22:18 Uhr

Danke für die schnelle Antwort,

das Löschen der obj-Ordner und einem neu erstellen nach neustart hat leider nichts gebracht.

Welche Informationen müsste ich denn bereitstellen oder was kann ich noch ausprobieren?

24.11.2013 - 21:30 Uhr

Hallo,

ich nutze seit einiger Zeit das WCF. Bisher hat alles gut geklappt. Ich habe im VS immer die Funktion: "Dienstverweis aktualisieren genutzt. Allerdings bekomme ich ab heute nur noch eine Fehlermeldung, dass die Referenz nicht zu finden ist. Wenn ich alle Dienstverweise ermitteln lasse, bekomme ich die Meldung, dass gar kein Dienstverweis in der Projektmappe zu finden ist ( es gibt im übrigen nur eine).
Ich weiß leider gar nicht wo ich anfangen muss zu suchen oder welche Informationen Ihr braucht um mir helfen zu können.
Ich hoffe jemand kann mir da etwas auf die Sprünge helfen.

Gruß
-Hades-

03.10.2013 - 20:17 Uhr

Vielen Dank für eure Antworten.

Zu Programmierhans: Redundant ist es schon, ob ich es nun in der Datenbank speicher oder nur in der Applikation zur Laufzeit, da ich die Daten, welche ja bereits eine Teilmenge der vorhandenen sind, neu erzeuge. Aber ich versteh schon was du meinst und ich werde es wohl auch so machen wenn sich keine andere Möglichkeit auftut.

Zu herbivore: Ich möchte ja den RowFilter nutzen und ich möchte die Time von den in der Datenbank gespeicherten Daten abfragen. Auf meine Min- und Maxwerte, welche ich über ein DateTimePicker festlege kann ich das natürlich aufrufen aber andersrum wüsste ich nicht. Falls das doch geht wäre ich über ein Beispiel dankbar.

Gruß
-Hades-

03.10.2013 - 12:43 Uhr

Hi,

ja entschuldige das war ein Fehler, DateTime ist es natürlich.
Ja eine eigene Spalte mit Time-Werten aus den DateTime-Einträgen erzeugen würde gehen, ist aber etwas umständlich und bescheert auch noch redundante Daten. Bin für alle Anregungen dankbar.

03.10.2013 - 09:57 Uhr

Hallo,

eine kurze Frage, ich möchte ein DatagridView mit Hilfe der Rowfilter-Eigenschaft filtern. Ich habe eine Spalte vom Typ DateTime. Diese filter ich bereits mit ≤ und ≥ . Allerdings möchte ich jetzt zusätzlich noch die Uhrzeit filtern. Das soll unabhängig vom Datum geschehen, also wirklich nur die Uhrzeit.
Es gibt keine Time() Methode oder dergleichen.

Hat jemand eine Idee wie ich ein DateTime nach der Uhrzeit zwischen einem Min- und Maxwert filter?

Gruß -Hades-

19.09.2013 - 18:55 Uhr

Ich hoffe das hat schon jemand getan. Aber könnte ja sein das das auch schon geht... etwas versteckt.

19.09.2013 - 18:18 Uhr

Nehmen wir mal die ImageBox des Datagridview, die bekommt auch nur ein Byte-Array und wandelt dieses selbstständig in ein Image um und zeigt es an. Eben diese Funktionalität wäre für die ComboBox wünschenswert, damit ich die DataTable nicht selbst zusammenbauen muss, da das Byte-Array über eine ID referenziert ist.

Denkbar wäre ja eine Eigenschaft der DatagridViewComboBox namens: ValueIsImage und alles wäre gut. 😉

19.09.2013 - 18:14 Uhr

Hi,

also ich habe kein Problem aus einem Byte-Array eine Bitmap zu erzeugen. Es geht darum ein Image in einer DatagridViewComboBox darzustellen. Eine ImageBox möchte ich nicht nehmen, dann müsste ich die DataTable selbst zusammenbauen. Da das Byte-Array für das Image aber schon in einer Tabelle referenziert ist wäre es viel schöner wenn das mit der ComboBox geht, dann könnte ich den Display- und Valuemember setzen und fertig.

19.09.2013 - 17:52 Uhr

Hallo,

ich würde gerne ein Bild in einer DatagridviewComboBox darstellen, am besten ohne Draw-Methoden überschrieben zu müssen.

Ich habe eine Tabelle, in der die ID für eine andere Tabelle hinterlegt ist. In dieser befindet sich das Bild. Also mit Text ist sowas ja sehr leicht mit einer Combobox und den Display- und Valuemember eigenschaften zu lösen. Das einzige was fehlt ist, den referenzierten Wert als Image anzeigen zu können. Stattdessen wird nur das byte-Array angezeigt.

Ich hoffe ich habe nur übersehen wie das geht oder womöglich hat jemand schon eine abgeleitete Klasse geschrieben die das ermöglicht?

Gruß -Hades-

03.09.2013 - 19:57 Uhr

Hallo f_igy,

danke für den Link. Demzufolge müsste mein TableAdapterManager, den ich für die Updates nutze, ja schon das hierarchische Einfügen beherrschen. Allerdings bekomme ich trotzdem die exception (neuerdings).

Also was ich ganz konkret habe und mache:

Ich habe simpel ausgedrückt die Tabelle Partner mit einem selbst erstelllten Guid Primärschlüssel. Daneben eine Tabelle Adresse, die die Partner-Guid als Fremdschlüssel enthält. Ich erzeuge mit einem typisierten Dataset erst den Partner, erzeuge die guid, erzeuge dann eine Adresse, setze die fremdschlüssel guid vom Partner und möchte diese beiden Zeilen dann mit Hilfe des TableAdapterManager committen. Da kommt dann die Exception.

Vorher war es sogar so, dass ich erst die Adresse committen konnte, ohne den Partner mit hochzuladen, ich habe also nur die mir bekannte Guid als Fremdschlüssel gesetzt und MySql hat nicht gemeckert, also auch nicht wenn die Guid auf die verwiesen wird gar nicht existiert.
Darauf aufbauend habe ich meinen Code erstellt, und da müsste ch jetzt wirklich eine große Menge von abändern wenn das so jetzt nicht mehr funktioniert...

03.09.2013 - 15:48 Uhr

Hallo,

es sind keine unterschiedlichen Transaktionen. Ich füge völlig neue Datensätze ein. Ich habe auch nicht das Datenbankschema verändert.
Das mit dem TableManager habe ich schon ausprobiert. Er macht zunäcst Inserts, allerdings funktioniert das auch nicht, da er wohl erst die "falschen" Zeilen inserten will, die aber den Fremdschlüssel (den es noch nicht gibt) beinhalten...

03.09.2013 - 15:16 Uhr

verwendetes Datenbanksystem: mySql 5.6.11

Hallo,

ich habe meine komplette Datenbank auf Guid für die Primärschlüssel umgestellt. Der Grund ist, dass ich den Schlüssel direkt selbst bestimmen möchte ohne den Umfang zum Datenbankserver. Dadurch kann ich dann mehrere Zeilen erstellen und die Fremdschlüssel zuweisen ohne vorher was committen zu müssen. Das hat auch alles wunderbar geklappt, bis jetzt.
Jetzt bekomme ich immer eine Exception: Cannot add or update a child row: a foreign key constraint fails

und zwar will er eine Zeile einfügen, die per Fremdschlüssel auf eine andere Zeile verweist, die aber noch nicht committed ist und demnach meint er das geht nicht.
Bis vorgestern wurde das allerdings problemlos committed.
Ich habe eine neue Xampp-Version installiert und damit auch eine neuere MySql-Version (denke ich). Ich denke es liegt daran aber vielleicht irre ich mich auch.
Weiß jemand wie ich das alte Verhalten wiederherstellen kann?
Ich benutze typed datasets, vielleicht kann man den TableManager ja auch etwas klüger machen, so dass er in der richtigen Reihenfolge einfügt??

Gruß -Hades-

17.06.2013 - 00:49 Uhr

verwendetes Datenbanksystem: MySql

Hallo,

ich schreibe gerade an einem Programm welches eine relativ große ( >40 Tabellen) Datenbank nutzt. Ich wollte hier nach Erfahrungen im Umgang mit den Datasets erkundigen. Zur Zeit habe ich mehrere ControllerKlassen geschrieben, welche jeweils Datasets besitzen und für bestimmte Teile der Datenbank zuständig sind.
Allerdings wird das mittlerweile recht viel Aufwand, da für jeden Controller Events geschrieben werden müssen und die Datasets geupdated werden müssen etc.
Da das theoretisch ja auch alles in einer Klasse mit einem TableAdapterManager und einem Dataset funktionieren würde bin ich mir nicht mehr ganz so sicher ob es klug war das alles so aufzuteilen.
Generell frage ich mich auch wie ich es am geschicktesten anstelle alles aktuell zu halten. Die naive Lösung ist natürlich die Datasets bei jeder Methode in der Informationen aus der Datenbank gebraucht werden erneut durch den TableAdapterManager zu füllen, was bei vielen Daten und vor allem wenn die Datenbank nicht lokal verfügbar ist, sehr lange dauert und nicht praktikabel ist.
Also würde ich jetzt die Datasets (oder ab jetzt vielleicht das eine Dataset) in einem Hintergrundthread komplett füllen. Damit wären die Daten lokal, allerdings brauche ich dann ein Konzept zum Updaten, da mehrere Clients auf die Datenbank zugreifen können und auch verändern können. Vielleicht gibt es dafür ja schon Mechanismen mit denen einige von euch Erfahrung haben.

Also die Fragen die ich mir stlele noch einmal als Stichkpunkte:

  • Ein Dataset für alles oder Spezialisierungen
  • Update-Mechanismus für die Datasets (mehrere Clients vorhanden)

Vielen Dank im voraus für eure Meinungen.

Gruß -Hades-

14.06.2013 - 14:02 Uhr

Ah ok,

das hört sich gut an, dann werde ich das wohl mal in einem Stresstest ausprobieren.

Falls das schonmal jemand getestet hat oder definitiv weiß das es funktioniert, bitte melden.

14.06.2013 - 13:46 Uhr

Um das Problem nochmal zu verdeutlichen: Nehmen wir an ich habe nicht nur einen Client der sein Dataset committed, sondern 1000 Clients die alle gleichzeitig ihre Datasets in die Datenbank schreiben lassen.
Jetzt muss ich in dem Event für jede Zeile garantieren können, dass Select last insert id auch genau die richtige ID für genau die behandelte Zeile liefert, ansonsten ist das nutzlos.

14.06.2013 - 13:34 Uhr

Hmm ja das ist klar FZelle,

aber was passiert wenn ich 1000 Zeilen in meinem Dataset hinzugefügt habe und für das Dataset jetzt über den TableAdapter committe und in die Datenbank schreibe.
Dann wird, wie du schon gesagt hast, das RowChanged-Ereignis für jede Zeile ausgeführt.
Ist denn jetzt garantiert, dass wenn ich per SELECT LAST_INSERT_ID() die ID hole das auch diejenige für genau die Zeile ist die ich in dem Event behandle?
Das DBMS wird ja kaum warten bis ich mein Event behandelt habe bevor es die nächste Zeile einfügt.

Ich hoffe es ist verständlich was ich meine.
Wenn in den Ereignisparametern schon die zurückgeliferte ID drin stehen würde wäre das kein Problem aber da habe ich ja nur den EreignisTyp (Commit)...

14.06.2013 - 12:37 Uhr

Hi FZelle,

also das mit dem Event hört sich an sich nicht schlecht an, jedoch frage ich mich ob das praktikabel ist. Die Sache ist, das ich nicht immer für jede Zeile im Dataset ein Update aufrufe, sondern ein Update für ein ganzes Dataset, in dem ich mehrere Zeilen geaddet habe.
Ich kann ja jetzt nicht garantieren das der "SELECT LAST_INSERT_ID()" Befehl genau die ID zu der Zeile für die ich gerade das Event behandle zurück liefert. Es kann ja in der Zeit in der das Event behandelt wird schon wieder eine neue Zeile geschrieben sein.?

Falls es doch einen Mechzanismus gibt mit dem ich in dem UpdateEvent genau die ID zu der Zeile bekomme wäre das natürlich besser.
Ansonsten würde ich dann jetzt die GUID´s einsetzen.

14.06.2013 - 01:51 Uhr

verwendetes Datenbanksystem: MySql

Hallo,

ich schreibe zur Zeit an einem Programm welches eine MySql-Datenbank nutzt. Ich verwende Visual Studio 2012 und nutze stark typisierte Datasets, da dies der bequemste Weg zu sein scheint.

Ich habe für alle Tabellen einen Primärschlüssel mit AutoIncrement-Attribut. Wenn ich ein Dataset, in dem ich mehrere Zeilen eingefügt habe mit Hilfe des TableAdapters in die Datenbank einfüge (Update-Methode), werden die Zeilen im Dataset nicht mit dem von der Datenbank vergebenen Primärschlüssel aktualisiert.

Die Werte brauche ich allerdings um Zuordnungen zu machen. Wenn ich zwei Zeilen mit gleichen Werten einfüge (theoretisch) kann ich ja auch nicht einfach nach den Werten in der DB suchen um den vergebenen Wert zu erhalten, außerdem ist das ja nicht unbedingt sehr performant.
Ich würde die Update-Commands auch ungerne umschreiben, da diese dann ja bei der nächsten Änderung der Datenbank überschrieben werden da der Code generiert wird.

Meine Frage also: Gibt es eine Einstellung, so dass die Zeilen des Dataset nach dem Update aktualisiert werden? (Wird der return der Kennung von MySql vielleicht gar nicht unterstützt?)
Wenn dem nicht so ist was würdet ihr vorschlagen? Ich denke ich würde mir dann eine eigene Kennung über GUID erzeugen, da mir das als die einfachste und eine funktionierende Lösung vorkommt.

Ich bin für alle nicht umständlichen Lösungen und Vorschläge offen. 😉

-Hades-

03.06.2013 - 15:25 Uhr

Hat denn noch niemand Erfahrung bezüglich Windows 8? Ich weiß es ist schon recht speziell aber ich hoffe jemand hat noch eine Idee.

31.05.2013 - 11:41 Uhr

Ich wollte das Thema noch einmal kurz pushen, in der Hoffnung das doch noch jemand eine Idee hat das schneller hinzubekommen oder vielleicht hat jemand noch einen ganz anderen Ansatz für Windows 8...

Gruß -Hades-

28.05.2013 - 17:39 Uhr

Hallo Herbivore,

ja das ist im generellen Fall schneller, da die Zeiten für ein Rechteck von 1x1 Pixel nicht sehr stark von 100x100 abweichen.
Leider ist das jetzt nicht die super Lösung, da selbst wenn man immer den kompletten Screen oder eben einen größeren Bereich, in dem sich alles befindet was man untersucht, nimmt und dann per LockBits weiterarbeitet ist das schon nach ein paar Wiederholungen sehr viel lamgsamer im Vergleich zu Bitblt unter Windows 7 etc.

28.05.2013 - 13:37 Uhr

Hallo MrSparkle,

vielen Dank für die Anregung, den Thread auf den du dich beziehst habe ich seinerzeit auch verfolgt und nutze LockBits auch immer, ist nicht zu schlagen. Leider geht es mir nicht darum auf Pixeldaten einer vorhandenen Bitmap zuzugreifen, sondern es geht darum zunächst die Pixeldaten vom Screen (aus einem vorgegebenen Rechteck) in eine Bitmap zu bekommen.

Danach nutze ich bereits LockBits um die Pixeldaten der Bitmap auszuwerten.

28.05.2013 - 12:16 Uhr

Hallo,

ich hatte in einem vorherigen Thema (siehe BitBlt dauert unter bestimmten Umständen (Aero?, Windows 8?) zu langsam) die schlechte Performance von Bitblt unter Windows 8 angesprochen. Das ist anscheinend durch den Window Desktop Manager zu begründen, da erst so etwas wie ein Schnappschuss erstellt werden muss um an die Pixeldaten zu kommen.
Die Lösung zu einer schnelleren Methode schien die Verwendung der Magnification API. Diese habe ich auch eingebaut und es sah zunächst auch sehr gut aus. Jetzt habe ich das aber mal genauer untersucht mittels Stopwatch und es zeigt sich, dass von "schnell" keine Rede mehr sein kann.

Selbst ein Rechteck von 1x1 Pixel aufzunehmen dauert mindestens immer 4ms und die Zeit geht hoch bis zu 20ms. Bei Bitblt unter Windows XP und darunter dauert das konstant 0ms (mit Stopwatch gemessen). Wenn man das ziemlich oft macht und z.B. Hautpartien in einem großen Bild finden will merkt man das deutlich, da die Verarbeitung dann von ca. einer halben Sekunde auf 15 - 20 Sekunden steigt...

Vielleicht habe ich abe auch irgendwo einen Fehler gemacht, daher erkläre ich kurz mein Vorgehen:

Ich habe die C++ Methoden für die Magnification-Routinen in einer DLL ausgelagert. Es gibt eine Routine, die ich im Vorfeld einmal aufrufe, welche das Host- und das Magnification-Window erstellt und MagInitialize() aufruft und die Transformationsmatrix anwendet. Zudem wird hier die Methode MagSetImageScalingCallback() aufgerufen, welche eine Callback-Methode registriert, in der ich die Pixeldaten abfange und in eine Bitmap umwandle (C# Seite).

Eine zweite Routine, welche ich immer dann aufrufe wenn ich ein Rechteck des Screens lesen will, nimmt die Handles der Windows und das Zielrechteck entgegen, ändert die Größe der Windows und ruft MagSetWindowSource() der Magnification API auf, damit die aktuellen Pixeldaten des Zierechtecks in das Magnification Window kopiert werden. Danach wird dann meine Callback-Methode aufgerufen, welche die eigentlichen Pixeldaten empfängt.

Die zweite Routine, die ich immer aufrufe sieht so aus:


DLL void GetBitmapForRectangle(HWND magWindowHandle, HWND hostWindowHandle, long bitmapDataCallBackPointer, int startX, int startY, int width, int height) 
{
	RECT sourceRect;
	sourceRect.left = startX;
	sourceRect.top = startY;
	sourceRect.right = width;
	sourceRect.bottom = height;

	SetWindowPos(hostWindowHandle, HWND_TOPMOST, 0, 0, width, height, SWP_NOZORDER | SWP_NOACTIVATE);

	SetWindowPos(magWindowHandle, HWND_TOPMOST, 0, 0, width, height, NULL);


	MagSetWindowSource(magWindowHandle, sourceRect);
}

Ich hoffe jemand weiß da einen Rat. Selbst wenn ich die SetWindowPos() Methoden rausnehme, was natürlich zu einem falschen Ergebnis führt, wird es nicht merklich schneller, es liegt also an MagSetWindowSource() denke ich.

Ich hoffe das man trotz Window Desktop Manager so etwas noch umsetzen kann ohne diese Performance-Einbrüche.

27.05.2013 - 19:26 Uhr

Ok funktioniert jetzt alles, danke für die Tipps.