Zitat von Th69
Und bei deinem Datensatz ist immer noch die Frage, warum hast du soviele einzelne Eigenschaften? Ist diese Klasse
AmazonKwEvaluationList
(der VariablenselectedRow
) automatisch generiert (erinnert mich von der Benennung an Excel-Spalten)?Einfacher wäre doch jeweils ein Array
Weeks[index]
,Prices[index]
, ... (und dann eine Schleife, um die Summe zu ermitteln).
Sorry, aber ich weiß nicht was ich noch mehr dazu schreiben soll. Du weißt doch sicherlich, wie man ein Array (oder List<...>
) anlegt?!
Wie füllst du denn diese Eigenschaften? Vllt. liegt ja da dein (bisheriger) Denkfehler?
Sorry, aber dein Code ist schlecht: UI-Code und Daten(haltung) sollte komplett getrennt sein (und für WPF solltest du - im eigenen Interesse bzw. dem Interesse der Firma - zwingend MVVM benutzen: [Artikel] MVVM und DataBinding und s.a. [Artikel] Drei-Schichten-Architektur).
Ich befürchte, daß auch dein anderer Code so ähnlich aufgebaut ist (und dann ist es mit Wartbarkeit und Wiederverwendbarkeit schlecht bestellt) - Page1.xaml.cs
hat mehr als 4000 Zeilen und anscheinend benutzt du #region
, um Zeilen im Editor auszublenden.
Du solltest die Daten aus Ressourcen laden, anstatt hartverdrahtet im Code (außerdem gibt es code-technisch viel bessere Möglichkeiten, als einzelne list.Add(...)
-Zeilen zu benutzen!).
Ich könnte dir jetzt deinen Fehler beschreiben, aber dann würdest du einfach so weiter machen...
Freut mich, daß ich dir (so einfach) helfen konnte. 😉
Dir auch noch einen schönen Sonntag!
Hallo und willkommen,
bei größeren Views benutzt man dazu eine hierarchische Implementierung(*), d.h. das Hauptviewmodel verwaltet dazu die Unterviewmodels (dies wird, in leichter Abwandlung, z.B. auch bei der Navigation zwischen verschiedenen Views genutzt), z.B.
public class MainViewModel : BaseViewModel
{
public PersonViewModel Person { get; private set; } = new PersonViewModel();
public TierViewModel Tier { get; private set; } = new TierViewModel();
}
So kannst du dann folgendes beim Binding benutzen:
<TextBox Text="{Binding Person.Name}" />
<TextBox Text="{Binding Tier.Name}" />
<!-- etc. -->
Oder du kannst auch einem ganzen Control dann ein Unterviewmodel als DataContext
geben:
<MyControl DataContext="{Binding Person}" Text="{Binding Name}">
<TextBox Text="{Binding Description}" />
</MyControl>
(*) s. z.B. (in englisch) Binding your View to your ViewModel in Wpf
PS: Die Erzeugung des ViewModels direkt im XAML-Code wird eigentlich nur bei kleinen Testprojekten aus Bequemlichkeit (bzw. zur Unterstützung im IDE-Designer) genutzt. Bei professionelleren Projekten sollte Dependency Injection (DI) benutzt werden (habe ich aus Einfachheit jetzt auch nicht im obigen MainViewModel
- mea culpa).
Ohne Code ist es aber schwierig dir zu helfen. 😉
Zitat von Feowlyn
Erste Teil meines Frages hast Du damit sehr gut beantwortet. Magst Du noch mal über letzte Hälfte scrollen, auch wenn es lang war?
Meinst du noch diese Frage?
Mich verwirrt auch noch, dass adapter nimmt ja 2 Parameter (dataset und "tabellenname" - ist dieser Tabellenname selbst zu geben oder muss es mit Datenbank übereinstimmen?
Du meinst die untere der beiden Überladungen von OleDbDataAdapter.Fill?
tblSource
ist dann der Name der DataTable
im übergebenen DataSet
(dieser sollte dann auch mit dem echten Datenbanknamen übereinstimmen).
Kannst du wenigstens die SQL-Abfrage zeigen?
PS: Access und OLE sind für professionelle Anwendungen auch nicht zu empfehlen. Besser sind echte Datenbanksysteme (wie MS SQL Server, MySQL, Oracle) oder aber lokale (embedded) Datenbanken (wie SQLite). Daher ist die gelesene Empfehlung weniger gegen das DataGridView
, sondern gegen Access (bei WPF hättest du ja denselben Datenzugriffscode).
Hallo und willkommen,
Zitat von Feowlyn
...
Ich mache mit using-Direktive eine OleDbConnection und eine OleDbAdapter, mache dann meine DataSet, fülle es mit adapter Hilfe, setze meine ListView auf Details, adde Spalten und mit foreach (für Zeilen als Subitems) die Zeilen mit .ToString() am Ende.
Zeige mal den Code (inkl. SQL-Anweisung) dazu.
Generell sollte nur für das Auslesen ein SQL-JOIN auch mit nur einer DataTable
funktionieren. DataRelation
zwischen verschiedenen DataTable
-Objekten bracht man nur, wenn man die Daten in separaten Tabellen im Speicher halten möchte und direkte Änderungen dazu dann auch wieder in der Datenbank abspeichern möchte (das geht bei SQL-JOIN-Anweisungen eben nicht).
PS: Deine Beschreibung liest sich auch so, als ob der gesamte Datenbankcode bei dir in einer Methode deiner Form
-Klasse ist?! Dann lies mal [Artikel] Drei-Schichten-Architektur
Und um Fehler zu Laufzeit finden, solltest du dich mit dem Debugger vertraut machen: [Artikel] Debugger: Wie verwende ich den von Visual Studio?
Edit:
Und für das Befüllen und Anzeigen aus Datenbank-Abfragen ist auch ein DataGridView
besser geeignet (Stichwort: Datenbindung [engl. Data Binding]), s.a. Vergleich DataGridView - ListView.
Jetzt verstehe ich, was du mit VisibilityBorder
und Spin
erreichen möchtest - du möchtest diese temporär ausblenden, während der Datenbank-Abfrage. So funktioniert das aber nicht, da die Änderungen erst erfolgen, wenn die gesamte Methode abgearbeitet ist (und die Windows- bzw. WPF-Nachrichtenschleife wieder ein Update der UI anstößt - s.a. [FAQ] Warum blockiert mein GUI?).
Hierfür benötigst du dann asynchrone Programmierung (async
/ await
/ Task<T>
), um auf die Datenbankabfrage zu warten.
Und bei deinem Datensatz ist immer noch die Frage, warum hast du soviele einzelne Eigenschaften? Ist diese Klasse AmazonKwEvaluationList
(der Variablen selectedRow
) automatisch generiert (erinnert mich von der Benennung an Excel-Spalten)?
Einfacher wäre doch jeweils ein Array Weeks[index]
, Prices[index]
, ... (und dann eine Schleife, um die Summe zu ermitteln).
Beim BoolToVisConverter
ist eine der beiden Methoden falsch implementiert (ich denke ConvertBack
), denn es muß ja einmal von bool
nach Visibility
konvertiert werden und in der anderen Methode genau umgekehrt.
Und beim Datenmodell meine ich: warum hast du dort kein Array (bzw. List<...>
), anstatt den zig Einzeleigenschaften?
Außerdem sollte die Klasse AmazonKwEvaluationList
besser ...Entry
oder ...Row
heißen (denn es handelt sich ja um einen einzigen Datensatz, keine Liste).
Kannst du nicht direkt an SelectedItem binden und in dessen Setter IsSelectCommand(value)
aufrufen?
Edit: Was ist denn das für ein Datenmodell, wo du Eigenschaften week_a
...week_z
,price_a
... price_z
, margin_a
...margin_z
(bzw. ..._aa
- ..._ay
) hast?
NPOI ist aber auch eine externe Assembly, so daß man dafür einen Verweis bräuchte (*).
Man müßte also, wie Palladin007 schon schrieb, selber eine DLL erzeugen und diese dann dynamisch laden (dies müßte man aber zuerst mal mit dem E-Cad Programm Eplan ausprobieren - je nachdem welche C#- und .NET-Version verwendet wird).
* Es gäbe zwar auch noch die Möglichkeit, alle NPOI-Sourcen zu einer Datei zusammenzufügen (aber dazu müßte man auch die Apache 2.0 Lizenz beachten) - und ob Eplan das dann direkt compiliert, hinge auch wieder von der verwendeten C#-Version ab.
Für die Google Cloud gibt es diverse .NET-Beispielprogramme: Google Cloud Platform .NET Docs Samples (u.a. cloud-sql )
Diese Beispiele zeigen jedoch den direkten Zugriff und Anzeige der Daten.
Für eine Web-API solltest du mit Tutorial: Erstellen einer Web-API mit ASP.NET Core starten.
PS: Dies solltest du jedoch nicht alleine umsetzen (da du bisher keine Erfahrung damit hast) - ich hoffe, es gibt noch andere erfahrene Entwickler bei euch, die sich mit Web-Sicherheit und Server-Datenbanken auskennen?
Andere Frage: Sind die Rechner denn nicht alle im selben Firmennetz? Dann könntet ihr doch (ersteinmal) einen Datenbankserver bei euch aufsetzen und eine firmeninterne Lösung erarbeiten (dies würde auch das Testen vereinfachen).
Ja, scheint wohl aus Kompatibilitätsgründen zu älteren Versionen so zu sein (auch wenn die SQLite-Entwickler es sich vorbehalten, es evtl. mal in Zukunft zu ändern), s.a. SQLite Foreign Key Support (s. "2. Enabling Foreign Key Support") - ich selber finde es auch sehr eigenartig.
SQLite ist auch nicht meine Lieblingsdatenbank (auch wenn es als lokale DB wenig Alternativen gibt) - insb. das File Locking Verhalten bei Multithreading DB-Operationen nervt.
Du mußt wohl nach jeder Verbindung zuerst PRAGMA foreign_keys = ON;
absenden, s.a. SQLite Cascade Delete.
Dies kannst du mit dem CellValidating-Ereignis durchführen und dessen Eigenschaft Cancel
setzen.
OK, exaktes JSON ist dies nicht, aber ähnlich dazu.
Im ersten Schritt könntest du ja einfach mal alle Blöcke in eine Liste einlesen, d.h. zuerst den Header überlesen und dann jeweils bis zur schließenden Klammer }
lesen (am besten du erzeugst dir für die Daten eine Klasse mit den Eigenschaften für Name, "_nameless..." sowie dem Block-Text).
So kannst du dann einfacher auf den Daten operieren (z.B. auch Suchfunktionen nach dem Namen z.B. "job_info"
schreiben).
Und wenn du dann die Daten spezieller auswerten möchtest, dann kannst du immer noch spezialisierte Klassen dafür (z.B. Job_Info
) erzeugen.
PS: Die zuletzt angefügten "job_info"-Blöcke sind aber noch fehlerhaft (dort fehlt z.B. die öffnende Klammer {
), oder?
Außerdem muß ganz unten noch die schließende Klammer für die 1.+2. Zeile "SiiNunit" + "{" stehen (bisher in Zeile 161774).
Edit:
Außerdem scheint es zu jedem job_info
-Block auch einen driver_ai
-Block zu geben, in der auf diesen mittels driver_job:
verwiesen wird.
Dazu mußt du dann aber auch wohl jeweils einzigartige Ids ("_nameless..."
) erzeugen (nicht die player
-Id verwenden)!
Ich, sowie T-Virus, meinen die Save-Datei (Textdatei).
Edit:
Ich habe mir mal gerade die "SII_Utilties.cs" angeschaut. Es wird dort fast in jeder Methode diese Datei immer wieder geladen:
Load_LAST_GAME_SII();
var lines = File.ReadAllLines(MainWindow.Global.TL_ETS_GAME_DRIVE_ENC_PATH);
Da wäre es wirklich eleganter und performanter, dies nur einmalig zu tun und dann die Daten vorzuhalten, so daß die Methoden nur auf diesen Daten operieren. C# ist ja eine objektorientierte Sprache, daher sollte man möglichst OOP benutzen (und statische Klassen bzw. Methoden nur für Hilfsfunktionalitäten einsetzen).
Und wenn du dann diese Funktionalität in einer Klasse hast, so hast du dann schon einen guten Ansatz für die Datenverwaltung (inkl. Jobs).
Zitat von Thommy1972de2
Das mit dem String.Empty hört sich gut an. Das wäre dann nach GetLines denke ich mal ?
Wo du bisher auch das "Remove Range"
hast (denn das entspricht dem ja).
Trotzdem wäre es m.E. besser einen Job-Parser (bzw. Serializer) zu haben, der die gesamten Daten als Objekte einliest und wieder abspeichert - und nicht nur nach einer bestimmten sucht und diese abändert (bzw. löscht und einen neuen Job einfügt). Aber dazu müßten wir mal eine gesamte Datei (bzw. einen relevanten Ausschnitt daraus) sehen - kannst es ja mal als Anhang anfügen.
Gibt es denn auch eine SII_Utilities.Write_LAST_GAME_SII()
, denn das Spiel wird doch sicherlich die verschlüsselte Save-Datei erwarten?
PS: Deine Variablenschreibweise (z.B. alles Großbuchstaben für Methodenparameter und Eigenschaften) ist äußerst ungewöhnlich und der Code ist damit schlecht(er) zu lesen.
Hallo und willkommen,
du könntest einfach die zu löschenden Zeilen im Array _input
auf String.Empty
setzen und dann den mit dem StringBuilder
erzeugten Text in _input[filePos_start]
setzen.
Und dann mit File.WriteAllLines(...)
wieder abspeichern (so brauchst du auch keine temp. List<string>
- hast dann allerdings entsprechende Leerzeilen).
Oder alternativ, wie bisher, in der List<string>
die Zeilen löschen und dann mit Insert(filePos_start, ...)
den mit dem StringBuilder
erzeugten Text einfügen - und dann ebenfalls mit File.WriteAllLines(...)
wieder abspeichern.
PS: Warum liest du die Datei denn wieder neu ein (die Daten, d.h. _input
, hat sich doch nicht verändert)?
Edit: Wenn es sich jedoch um eine Json-Datei handelt, dann solltest du auch einen Json-Parser verwenden.
Entweder auch dort eine große Schriftart angeben und dann im DrawItem-Ereignis mit einer kleineren Schriftart zeichnen oder aber eine Dummy-ImageList angeben, s. z.B. C# - ListView Item Spacing (Padding) oder Setting Row Height of ListView.
Hallo und willkommen,
du müßtest dann den Text (+ CheckBox) selber zeichnen (Stichwort: OwnerDraw
) - ein paar Anregungen dazu gibt es in Can I use a DrawItem event handler with a CheckedListBox?
Edit: Evtl. wäre eine ListView mit View = View.Details
und CheckBoxes = true
einfacher zu benutzen?
BlonderHans, du hast noch einen kleinen C&P Fehler in
private async Task OnPage2()
{
CurrentPage = _page2;
await _page1.InitializeAsync();
}
Jetzt hast du aber eine 180° Wende vollzogen. Dies hat dann mit MVVM nichts mehr zu tun. Warum benutzt du denn jetzt DependencyProperty
(dies benötigt man, wenn man in einer View bzw. einem Control eine Eigenschaft bindungsfähig machen möchte)? Oder hast du dich von dem Begriff Dependency Injection fehlleiten lassen?
Du hattest doch schon
<ContentControl Content="{Binding CurrentViewModel}" ... />
zum Wechseln der View (anhand des ViewModels).
Hast du denn auch das passende DataTemplate
(in Window.Resources
) dafür erstellt gehabt (für die Zuordnung ViewModel → View)? Dies hattest du bisher nicht gezeigt, ansonsten s. z.B. die Antworten in WPF DataContext nicht über Code-Behind? (ab "Im Folgenden ...) und Binding ContentControl Content for dynamic content.
In deinem vorherigen Code hast du einfach die zu dem PageXViewModel
gehörende Eigenschaft zu setzen:
Page1ViewModel.FirstName = "Max";
Ich hoffe, du hast diesen Stand noch gesichert.
Und wenn du damit immer noch nicht weiterkommst, dann hänge mal dein gesamtes Projekt als Anhang an deinen Beitrag.
Das habe ich doch geschrieben, daß du die falsche FirstName
-Eigenschaft änderst!
Schau dir nochmal genau den Code in NavigationThroughPages
an (bzw. debugge ihn)!
Die Frage ist auch, ob du die MainViewModel.FirstName
-Eigenschaft überhaupt benötigst (bzw. was sie genau darstellen soll)?
Edit:
Jetzt erst sehe ich deinen Hauptfehler.
Du erzeugst verschiedene PageXViewModel
-Instanzen, einmal im MainViewModel
und dann jeweils in dem XAML-Code der UserControl
-Objekte (und nur diese sind an DataContext
gebunden)!
Edit2:
Ich kann dir nur raten, dich nochmal intensiv mit den Grundlagen von MVVM (DataBinding perDataContext
) zu beschäftigen bzw. andere MVVM-Tutorial-Projekte anzuschauen, s.a. mein Beitrag in DataGrid / Dateneingabe in MS SQL Datenbank speichern.
Hallo,
du möchtest anscheinend FirstName
in den beiden Page
-Objekten ändern?
Dann hast du noch einen logischen Fehler in deinem Code: du hast je PageXViewModel
eine eigene Eigenschaft FirstName
gebunden, änderst aber im MainWindowViewModel
(in NavigationThroughPages(...)
nur dessen eigene FirstName
-Eigenschaft!
Außerdem noch ein paar andere Fehler/Verbesserungen:
MainWindowViewModel()
erzeugst du eine lokale Variable users
, benutzt diese aber in einer anderen Methode. Dieser Code dürfte also gar nicht kompilieren (außer du hast noch eine andere Variable users
definiert)!DelegateCommand
-Klasse läßt sich noch codetechnisch etwas vereinfachen:
CanExecute
reicht return CanExecutePredicate?.Invoke(_object) : true;
Execute
ist die if
-Anweisung überflüssig (da du ja ?.
beim Aufruf benutzt)Hallo Joe,
auffüllen kannst du den String auch, ohne diesen erst in eine Zahl zu verwanden: String.PadLeft
Zitat von Abt
Zitat von steeveKa1
Warum ist aber myEnumerator nun ein Objekt vom Interface IEnumerator?
Ist er nicht. Es ist ein Inteface. Das siehst Du auch, wenn Du den konkreten Typ verwendest statt var.
var ist bequem, aber leider verschleiert das viel. Wenn Du Dir also nicht sicher bist: verzichte auf var.
Das liest sich jetzt aber so, als ob man jetzt statt var
den konkreten Typ hinschreiben soll, aber das geht natürlich nicht, sondern der Rückgabetyp ist ja explizit IEnumerator
und der konkrete Typ wird erst zur Laufzeit erzeugt.
Hallo und willkommen,
als Anwender der GetEnumerator
-Methode wird nur mit dem Interface IEnumerator
gearbeitet (wie in deinem Code), die Methode selbst gibt jedoch (je nach Klasse) ein dafür passendes Objekt einer davon abgeleiteten/implementierten Klasse zurück. Im Falle vom Array
die Klasse ArrayEnumerator welche von Array.GetEnumerator() benutzt wird (bzw. für generische Arrays SZGenericArrayEnumerator<T>).
Du kannst ja mal in deinem Code myEnumerator.GetType()
ausgeben lassen.
Hallo Timm,
schau dir am besten mal ein einfaches WPF MVVM-Datenbankprojekt an, wie z.B.
ICommand
, sondern auch im Codebehind ButtonClick
- aber dafür verwendet es verschiedene Datenbankoperationen sowie zum Datenbankzugriff ein Repository (s.u.).RelayCommand
als ICommand
-Implementierung als auch verschiedene Views und ViewModels. Zum Datenbankzugriff jedoch verwendet es das veraltete LinqToSQL sowie direkte Datenbankprozeduren - dies kann man aber selbstverständlich durch ein anderes ORM ersetzen.Bzgl. deiner Fragen:
Beim DelegateCommand ist mir nicht klar warum als parameter "null" übermittelt wird. Nach meinem Verständnis kann ein Button doch nur geklickt also True oder nicht geklickt False liefern.
Meinst du beim Konstruktor public DelegateCommand(Action<object> execute) : this(null, execute) { }
? Dies ist der Parameter canExecute
, welcher angibt, ob das UI-Element (hier Button
) aktiviert ist oder nicht (d.h. ausgegraut). Bei Angabe von null
ist dieser immer aktiv (s. Implementierung von CanExecute
).
Auch ist mir nicht ganz klar, wo der nachfolgende Programmcode hingehört:
Die gesamte Funktionalität der Methode Btn_GO_Click
wird aufgeteilt auf verschiedene Methoden (in unterschiedlichen Schichten/Klassen):
DelegateCommand
eine Methode als Parameter execute
übergeben, welche dann in dessen Execute
-Methode automatisch ausgeführt wird.Hast du die Eigenschaft SessionEndingCancelEventArgs.ReasonSessionEnding abgefragt?
Hast du schon in Unterstützung hoher DPI-Werte in Windows Forms geschaut?
Hast du denn auch die XML Dokumentationsdatei erzeugt (bzw. weitergegeben, d.h. neben der Assembly-DLL)?
Hast du eine "App.config" in deinem Projektordner?
Hallo,
so wie ich deinen Code verstehe, hast du ein zeitliches Problem (was durch die MessageBox
kaschiert wird).
Ohne den MessageBox
-Aufruf ist die Liste option1.StkList
leer (so daß der Zugriff auf Index 0
die Exception auslöst). Im Konstruktor von TWSInterface
erzeugst du diese leere Liste, gefüllt wird sie aber nur in securityDefinitionOptionParameter
(welche anscheinend in DataForOptionsRow
durch ClientSocket.reqContractDetails(...)
asynchron aufgerufen wird).
Du mußt (logisch / zeitlich) sicherstellen, daß die Daten erst komplett eingelesen sind, bevor die weitere Abarbeitung erfolgt. Am besten beschäftigst du dich mal mit der asynchronen Programmierung (Task<T>
/async
/ await
).
PS: Die Schleife while (NextOrderId <= 0) { }
, um auf das Setzen einer Variablen (aus einem anderen Thread) zu warten, ist ein No-Go (so erzeugst du 100% Kernlast)!
Und auch der Dispatcher
-Aufruf ist m.E. dort unnötig (bzw. an der falschen Stelle): eine ObservableCollection<T>
per se benötigt dies nicht, nur wenn sie an ein UI-Element gebunden ist.
Vielen Dank für das Hinzufügen der Links (Artikel + FAQs) zum Texteditor - jedoch sind alle Umlaute als &#x..
dargestellt (oder ist das nur beim akt. Firefox so?).
Algorithmisch ist das mit den 2 verschachtelten Schleifen schon richtig so: O(N*M).
Du kannst aber auch die innere Schleife in eine eigene Methode auslagern oder aber gleich List<T>.Contains(...)
/ List<T>.Exists(...)
bzw. mittels LINQ Any(...)
aufrufen.
PS: Ich hoffe mal, daß deine beiden Klassen im realen Code nicht ListeX
heißen?!!
Hallo,
was soll denn die Zeile im Windows_Loaded
-Ereignis bewirken?
Du mußt schon den DataContext
setzen, s.a. [Artikel] MVVM und DataBinding (unter "2.2 Instanziierung des ViewModels").
Ich verstehe auch nicht, wieso du dies nicht direkt im Konstruktor setzt? Am besten wäre sogar mittels Dependency Injection (DI) direkt das ViewModel als Parameter zu übergeben (anstatt dessen Parameter und dieses dann zu erzeugen).
Edit: Und bzgl. deinem 2. Beitrag solltest du von einem ViewModel nicht direkt auf eine View zugreifen (bzw. diese von dort öffnen). Besser ist es einen Service dafür zu nutzen, s. z.B. die Antwort in C# – WPF Open a new View from the ViewModel.
Sorry, hatte gerade meinen Beitrag noch mal editiert (da er leicht fehlerhaft war).
PS:
Beim Zugriff auf die Attribute muß vorher überprüft werden, ob der XmlNode
ein XmlElement ist (denn nur diese abgeleitete Klasse besitzt die entsprechende Methode), also z.B.
if (subNode is XmlElement subElement)
string s = subElement.GetAttribute("qualifier").ToString();
Hallo,
dein 2. Ansatz ist schon auf dem richtigen Weg, aber der Rückgabewert von XmlNode.SelectNodes ist die Liste der gefunden Elemente (sonst könnte man ja gar nicht die Schleife damit benutzen), also
var parentNodes = doc.SelectNodes("//start//dispatch_status_entries");
foreach (XmlNode parentNode in parentNodes)
foreach (XmlNode subNode in parentNode.ChildNodes)
// oder alternativ
var subNodes = doc.SelectNodes("//start//dispatch_status_entries//*"); // navigiere mit * explizit alle Unterelemente
foreach (XmlNode subNode in subNodes)
Bisher hast du mit subNode["entry"]
immer nur auf den ersten Untereintrag zugegriffen.
Und dann kannst du bei jedem subNode
direkt auf den InnerText
sowie die Attribute zugreifen:
str4 = "4 = " + subNode.InnerText;
str5 = "5 = " + subNode.GetAttribute("qualifier").ToString();
Bedenke, daß nach der Schleife in str4
und str5
jeweils nur die Texte des letzten entry
-Eintrags stehen, da diese (bisher) immer wieder neu zugewiesen werden!
Dann solltest du Sicheres Speichern von App-Geheimnissen bei der Entwicklung in ASP.NET Core durchlesen.
Noch besser ist es, gar kein Passwort angeben zu müssen, d.h. Integrated Security=true
(also die Windows-Anmeldedaten) zu nutzen.
Ich nehme an, du benutzt .NET (Core) - und nicht noch das .NET Framework!? Dann mußt du das zu der .NET-Version passende NuGet-Paket System.IO.Ports einbinden.
PS: Falsches Unterforum (besser wäre wohl Rund um die Programmierung - evtl. verschiebt es ein Moderator?).
Falls es eine größere (komplexere) XSD ist, dann kann man auch beide Ansätze kombinieren (Stichwort: IXmlSerializable
): How to customize XML serialization
In C# – Correct XML serialization and deserialization of “mixed” types in .NET wird ein ähnliches Problem (bzgl. Mixed Mode und Reihenfolge der Elemente) beschrieben sowie unter "Best Solution" die Lösung dafür. Dort sind aber wohl die Knoten eigene Klassen (bzw. Strukturen), anstatt enum
-Elemente und es wird dann object[]
als Datentyp benutzt.
Ich habe aber auch in dem MSDN-Artikel The XML Files: Advanced Type Mappings diese generelle Aussage gefunden:
Figure 4 Deserialize
...
Q Can XmlSerializer deal with mixed content models?
...
There are many XML structures that are perfectly reasonable in XML Schema but don't make much sense in the world of the .NET Framework (like choices or mixed content models). So if you're designing a system that relies heavily on the use of mixed content models, you're better off avoiding XmlSerializer altogether. Instead, you should use something like XSLT, which is well suited for processing document-oriented structures.
Zitat von Quaneu
Ich habe nachträglich das Text Property entfernt und
XmlText(typeof(string))]
bei Items hinzugefügt, damit ich es "richtig" lesen kann.
Geht es dir darum, daß die Reihenfolge der XML-Einträge erhalten bleibt? Denn mit dem initial von XSD erzeugten Code sollte es doch fehlerfrei gelesen werden können.
Und gibst du das Schema beim Deserialisieren mit (denn dort ist ja Text
nicht definiert)?
Was passiert denn, nachdem du Text
zu dem ItemsChoiceType
hinzugefügt hast, wenn du die Zeile [XmlText(typeof(string))]
dann austauschst mit [XmlElement("Text", typeof(string))]
?
Hallo und willkommen,
ich befürchte, dein Projekt ist zu anspruchsvoll, denn m.E. ist die größte Herausforderung, für dich als Hobbyprojekt eine kostengünstige PDF-Library zu finden (s.a. die Antwort in Webentwicklung MVC Versand PDF). Denn gerade die Punkte "Metadaten zu den PDF, Tags" sowie "Zusammenstellen einzelnen PDF zu einem neuen Dokument (PDF)" wirst du ohne diese nicht umsetzen können.
Edit: Von den drei im Link erwähnten scheint aber zumindestens QuestPDF frei für nicht-kommerzielle Projekte zu sein. Du müßtest aber mal evaluieren, ob diese deine Anforderungen erfüllt.
Zu deiner Frage bzgl. Entwurfsmuster kommt es darauf an, ob du als GUI Windows Forms oder WPF verwenden möchtest. Generell gilt [Artikel] Drei-Schichten-Architektur sowie für WPF [Artikel] MVVM und DataBinding.
Und SQLite als lokale Datenbank ist quasi Standard im .NET-Umfeld geworden (auch wenn es noch andere Embedded Datenbanken gibt).
Dann such doch einfach nach dieser Fehlernummer - hier für dich: MSSQLSERVER_18456
@Abt: Ich will ja nicht nerven, aber es sind zurzeit die letzten 7 Themen in .NET-Komponenten und C#-Snippets (2x von Elmo84) im falschen Subforum - vllt. doch eine bessere Lösung dafür finden (als dieses Subforum als Standardauswahl zu nehmen)?
@T-Virus: Dein 1. Link ist aber nur die Haupt-.NET-Dokumentation.
Meinst du nicht eher ASP.NET-Dokumentation?
Du müßtest für jeden Unterpfad jeweils den Indexoperator benutzen, d.h. bei einem Pfad "x:y:z"
dann @model.MyJson[x][y][z]
.
Wenn du unterschiedliche Pfadtiefen hast, dann wird das schwieriger. Aber schau dir mal die Methode GetNestedJsonData
in einer der Antworten in Getting data from a deeply nested json object an (ich weiß nur nicht, wie du diese dann in Razor integriert bekommst).