WPF verfügt über Validierungsstrategien in Zusammenhang mit Databinding.
Das würde dir einiges an Arbeit abnehmen und die Arbeit mit der UI konsistenter machen.
Ein Client ist nicht verbunden in dem Sinne.
Bei HTTP gilt, die Verbindung des Clients ist ein Request. Danach ist er nicht mehr verbunden.
Scoped lebt über genau einen Request. Innerhalb eines Requests bekommst du immer die gleiche Instanz der Klasse.
Bei Transient bekommst du jedes mal eine neue Instanz.
Das kannst du nur sicher sagen, solange die Datei nur auf deinem System war.
Wenn sie über verschiedene Systeme gegangen ist ist das "Erstellungsdatum" des Dateisystems nicht mehr zuverlässig. Vor allem dann, wenn es über unterschiedliche Dateisysteme gegangen ist.
So als Ansätze (weiß allerdings nicht ob die gut sind :)):
- Du könntest ein SVG erstellen und rendern
- Du könntest mithilfe des <Path> Controls etwas zeichnen
- Du könntest 4 Bilder eines Kartons erstellen und darstellen
Ich habe jetzt das Video nur überflogen, aber wie es aussieht wird da vom WPF Client direkt auf die datenbank zugegriffen, was durchaus als Bad Practise bezeichnet werden muss.
Ziel sollte es sein, niemals direkt mit einer Applikation die im Dunstkreis eines Endusers läuft auf eine Datenbank zuzugreifen.
--> Abstraktion über eine API (das kann HTTP mit REST sein, gRPC, ....) das erlaubt dann eine granulare Kontrolle über das, was in der Datenbank ausgeführt wird und benötigt nachher keine Datenbankcredentials auf dem Client PC.
Bei uns ist auch Homeoffice angesagt, soweit es geht.
Die Produktion (Geräte, keine Software :)) läuft soweit weiter, es wurde die Reinigung der Flächen erhöht und Sorge getragen, dass die Kollegen zwei Meter Abstand halten können, Pausenregelungen, Kantinenregelungen usw. wurden entsprechend auch verabschiedet.
Wirtschaftlich merken wir wohl etwas aber scheinbar nichts besorgniserregendes, sonst hätte es eine AdHoc Meldung für die Börse gegeben.
In der Regel [...] verbindet man eine Client Applikation niemals direkt mit der Datenbank, sondern setzt einen Abstraktionslayer (idr eine WebAPI) dazwischen.
und nur der Vollständigkeit halber ist eine WebAPI nicht der Weisheit letzter Schluss, es gibt hierfür auch andere Technologien, wie z.B. gRPC
die Frage ist, was genau du erreichen möchtest.
In der Regel (Ausnahmen wären z.B. Datenbank Administrationstools wie z.B. SQL Server Management Studio) verbindet man eine Client Applikation niemals direkt mit der Datenbank, sondern setzt einen Abstraktionslayer (idr eine WebAPI) dazwischen.
Für die WebApi gibt es gängige Authentifizierungsmethoden, die dir dann diese Arbeit abnehmen.
Edit als Hintergrundinfo:
Das ganze macht man aus Sicherheitsgründen:
damit niemand die direkten Datenbankzugangsdaten kennt/kennen muss
damit man genau kontrollieren kann, was auf der Datenbank passiert
damit die Datenbank nicht öffentlich erreichbar sein muss
damit man die etablierten Sicherheitsmechanismen, die auf dem http Protokoll aufbauen nutzen kann
visuelle Elemente, die dir Windows Forms bietet.
Z.B. einen Treeview. Ich bin nicht so firm, was Windows Forms angeht, aber es wird sicherlich auch Elemente, wie ein ListView geben.
Definiere, was du unter Vergleichen verstehst und was der FTP Server unterstützt.
Wenn Vergleichen heißt, dass die Dateien auf Byte-Basis exakt gleich sein müssen bleibt nur herunterladen (oder hochladen) und vergleichen, sofern der Server keine Checksummen versteht.
Wenn Vergleichen aber für dich heißt, gleiche Größe und gleiches Änderungsdatum, dann kann das FTP sehr wohl leisten, denn die Informationen bekommst du bei einem Listing mitgeliefert.
Nein, aber du bekommst ein Komplett Produkt, zu dem du dir auch Support kaufen kannst und nicht alles alleine konfigurieren musst.
Gerade, wenn du nicht Experte für getunnelte Remote Verbindungen bist, baust du dir selber schneller einen offenen Angriffsvektor, als du chauen kannst.
C# Interactive könnte so funktionieren (oder ähnlich).
Du kannst auf deine Klassen und deren Methoden zugreifen und Zustände erzeugen.
Ob das aber so optimal ist kann ich nicht beurteilen - da habe ich nicht genug Erfahrung.
In dem von mir verlinkten Artikel ist es gut beschrieben. Wenn du eine Schichtentrennung zwischen Datenhaltung und Datenpräsentation einführst und eigene Klassen in den Schichten hast, musst du zwischen diesen Klassen eine Projektion erzeugen.
Für die Projektion kannst du AutoMapper verwenden - musst es aber nicht.
Das Grundproblem (aber nicht die Lösung) ist, dass Entity Framework per default bei 1:n Verknüpfungen automatisch alle Datensätze mitlädt. Vermutlich ist, wenn dein Model gerendert wird, bereits die Datenbank Verbindung wieder geschlossen und damit können die Datensätze nicht automatisiert nachgeladen werden.
AutoMapper würde bei einer ausgeführten Projektion die Datensätze aber zugreifen wollen und diese damit nachladen (gesetzt dem Fall, du hast EFCore so konfiguriert, dass es das tut - ich bin aber nicht sicher, ob es das in der aktuellen Version überhaupt kann, ich habe das zum letzten mal in EF 6 benutzt).
Edit: verlinkt ist nicht gepostet - im Text korrigiert
Ich muss gestehen, mein WPF ist schon etwas her.
Ich hätte das vermutlich mit einem DataTemplate gelöst und gefilterte Termine in einer Property Collection bereitgestellt :)
Vermutlich liegt aber Prinzipiell aber da auch das Problem. Du verwendest in der View-Schicht die Datenbank Entitäten. Würdest du eine Projektion erzeugen, bei der nur eine Personenliste existiert und das Personen-Model bereits eine eigene Collection mit Terminen hätte, würde alles funktionieren, denn du kannst ja auch die Properties der Personen Instanz zugreifen.
Von den Vorteilen bleibt nur "kann andere ASP.NET Teile verwenden" und das ist auch der Vorteil schlechthin in dem Fall.
Der gRPC Service lässt sich einfach als Endpoint einbinden (via MapEndpoints im Startup) und du ersparst dir das Hosting selber.
sind die Termine direkt an das Person Objekt als Property gebunden (a) oder hast du eine extra Collection mit Terminen (b)?
Gibt mehrere Lösungen, deine ListBox hat eine SelectedItem Property, welche du an eine Property im ViewModel vom Typ Person binden kannst. Wenn sich diese ändert (im Setter),
a) deine Termindarstellung einfach an das SelectedItem der Listbox direkt im XAML binden
b) kannst du einfach deine Termine filtern und in einer extra Collection anbieten
-> Wenn du es verteilen willst, besorge dir ein Zertifikat zum Signieren, von einer vertrauenswürdigen Zertifizierungsstelle.
-> Wenn es nur für dich ist, erzeuge dir selber ein Zertifikat zum signieren und installiere es im Windows Zertifikatsspeicher.
Der Namespace "d" ist meines Wissens immer vordefiniert, den solltest du nicht ändern. Generell hat dieser Einfluss auf den Designer (im Originalzustand).
Das klingt nach einer Schichtenverletzung der [Artikel] Drei-Schichten-Architektur .
Dein UI (=XAML) sollte nichts von deinem Datenlayer (=XML via XDocument, XElement) wissen.
Das Tutorial wurde für .NET Framework 2.0 geschrieben.
Prinzipiell funktioniert das alles noch, aber gerade bei IO gibt es seit ein paar Jahren Nebenläufige Konzepte mit async & await, die sich in vielen der API's wieder finden.
Das ist vor allem dann praktisch, wenn du mit UI's arbeitest.
Nutze ein Command, bzw. ein RelayCommand innerhalb deines ViewModels, dass du an den Löschen Button bindest (anstatt des Click Handlers in der Code Behind). dann kannst du aus dem RelayCommand auf die per Databinding gekoppelte Property des ViewModels mit dem Selected Item zugreifen.
MVVM in WPF bietet nicht nur Databindings, sondern auch Command Bindings.
Im besten Fall ist in der CodeBehind nur ein Aufruf an InitializeComponent();
P.S.: Das Binding hat als Inhalt nicht die ID, sondern ein Stand Objekt.
Den Exit Code musst du weiterhin aus der Main method zurückgeben.
Eine "globale Variable" ist nicht notwendig, hierfür kannst du das gleiche Konstrukt verwenden, wie Microsoft für den IApplicationLifetime verwendet: Ein im Dependency Injection registriertes Singleton, dass du allerdings vorab instanziierst und zur Kommunikation zwischen deinem HostedService und der Main Methode verwendest.
Das, was du da machst nennt sich Boxing.
Natürlich kannst du nur auf die Methoden und Properties der Klasse HeroClass zugreifen, die anderen sind dir ja nicht bekannt.
Um das zu lösen gibt es tendenziell mehrere Möglichkeiten:
-> der is Operator
HeroClass currentHera = ...;
if (currentHero is Batman batman) { batman.skill3(); }
elsif (currentHero is Robin robin) { robin.skill5(); }
-> Die Methoden so wählen, dass du in der Basisklasse damit umgehen kannst
Du könntest deine HeroClass so gestalten, dass z.B. eine Attack(HeroClass victim) Methode als abstract deklariert existiert. Jeder von HeroClass erbende Implementierung dann Attack() implementieren und könnte unterschiedliche Effekte haben.
Das ist vermutlich (vermutlich, weil ich deinen eigentlichen Anwendungszweck nicht kenne) Architektonisch die schönere Lösung.
-> Verschiedene Implementierungen des Visitor Patterns, die die unterschiedlichen Implementierungen kennen, z.B. mittels Factory Klasse (das wäre aber nur eine Abwandlung der ersten Lösung mit dem is Operator).
Aus meiner Erfahrung: meist sind solche proprietären Protokolle von den Herstellern nicht öffentlich dokumentiert und werden auch nicht öffentlich kommentiert.
Lösungen für den Seiteneffekt wären ja an sich ganz einfach zu implementieren:
-> Anderen Port nutzen
-> Singlecast nutzen
-> Netzwerk so wählen, dass nur die relevanten Teilnehmer deinen Broadcast bekommen (Firewall)