Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Portal
  • |
  • Mitglieder
Beiträge von Palladin007
Thema: CustomControl wird in XAML nach geändertem AssemblyName nicht gefunden
Am im Forum: GUI: WPF und XAML

Hi,

ich arbeite mit WPF, .NET 5 und VS2022 Preview.
Außerdem habe ich eine Directory.Build.props, in der ich Firmen- und Projekt-Name vor Namespace und Assembly hänge.

Die Directory.Build.props enthält also sowas:


<PropertyGroup Condition="!$(MSBuildProjectName.StartsWith('$(ApplicationName).'))">
	<RootNamespace>$(ApplicationName).$(MSBuildProjectName)</RootNamespace>
	<AssemblyName>$(ApplicationName).$(MSBuildProjectName)</AssemblyName>
</PropertyGroup>

$(ApplicationName) ist dann z.B. "Firma.Produkt".

Im Startprojekt habe ich ein CustomControl vom Template hinzugefügt.
Es wurde also ein CustomControl.cs und eine Generic.xaml erstellt, in der dann der Style für das Control steht.

Die XMLNS-Definition:

xmlns:local="clr-namespace:Firma.Produkt.MyApp"

Das Problem ist:
Mit der AssemblyName-Zeile in der Directory.Build.props funktioniert es nicht.
Nehme ich die AssemblyName-Zeile aus der Directory.Build.props raus, funktioniert es.

Folgender Fehler:

Fehler
The name "CustomControl1" does not exist in the namespace "clr-namespace:Firma.Produkt.MyApp".
The name "CustomControl1" does not exist in the namespace "clr-namespace:Firma.Produkt.MyApp".
Cannot find the type 'local:CustomControl1'. Note that type names are case sensitive.

Die Namespaces habe ich gefühlt 100 Mal kontrolliert, die stimmen also.
Namespace und AssemblyName sind - wie man oben sieht - auch identisch.
Der XAML-Editor erkennt mein Control auch, zumindest bietet er es mir in der Intellisense an.


Ist das ein Bug?
Habe ich was übersehen?

Im Anhang ist ein minimalistisches Beispiel-Projekt, einfach die AssemblyName-Zeile in der csproj ein- bzw. auskommentieren.

Thema: Exception trotz try-catch
Am im Forum: Grundlagen von C#

Zitat von PierreDole
Sorry, mein Edit und Dein Post haben sich überschnitten.

Wenn man MemoryExceptions nicht abfangen kann, gibt es dann wenigstens eine Möglichkeit zu überprüfen, ob auf jene Stelle im Memory gerade zugegriffen werden kann?

Die konkrete Stelle hilft dir nicht weiter, die .NET Runtime schaufelt doch immer hin und her - solltest Du das verhindern/umgehen, dann hast Du schon deinen Fehler
Und ich denke, Abt meint die OutOfMemoryException. Wann die geworfen wird, steht in der Doku und dann hat man nicht nur irgendeine Stelle im RAM.

Thema: Exception trotz try-catch
Am im Forum: Grundlagen von C#

Steht doch in der Doku: AccessViolationException Class (System)

Thema: Zugriff auf Methoden generischer Objekte
Am im Forum: Grundlagen von C#

Was Du vor hast, wird so funktionieren, langfristig aber zu Problemen führen
Du machst damit die Klassen von den in einer Methode fix definierten Parameter abhängig und musst bei jeder Änderung daran denken, dass Klasse und Reflection-Code noch zueinander passen müssen.
Zum Spielen und Reflection kennen lernen, ok, aber sobald daraus ein tatsächliches Projekt wird, solltest Du lieber andere Wege suchen.

Für Datenbanken wären das z.B. EFCore, das hat das gleiche Problem, hat aber auch viel Logik nur dafür, dass diese komplexen Reflection-Zusammenhänge genau so funktionieren, wie man es erwarten würde.
Für alles Weitere könnte man auf Konzepte wie das Factory-Pattern zurückgreifen oder sein Vorhaben überdenken, dass man gar keine dynamisch erzeugten Instanzen braucht.
Selbst implementierte Reflection würde ich immer möglichst vermeiden oder wenigstens klein halten.

Thema: Zugriff auf Methoden generischer Objekte
Am im Forum: Grundlagen von C#

Das geht nur mit Reflection.
Du suchst dann per Reflection die Properties oder den Konstruktor, den Du brauchst und arbeitest damit.

Oder Du erfindest ein Interface, dem Du eine Methode gibst, das Name und Wert bekommt.
Die Implementierung muss dann je nach Entity separat schauen, was das ist und wie man es setzt.

Aber was Du versuchst, wurde schon zig Mal entwickelt, nennt sich ORM.
Z.B. EFCore, nHibernate oder Dapper.
EFCore ist vermutlich der modernste ORM, wo nHibernate heute steht, weiß ich nicht.
Dapper ist sehr einfach gestrickt und beschränkt sich auf das Mapping (das, was Du versuchst), während EFCore und nHibernate die komplette Datenbank-Schicht abbilden können, sodass am Ende gar kein (oder kaum) SQL mehr notwendig ist.

Wenn es dir nur um den Spaß an der Freude oder Übung geht, dann liegt es bei dir, was Du versuchst.
Produktiv würde ich aber immer auf einen der ORM setzen, entweder EFCore oder Dapper, je nach Anforderungen.
Eine eigene Reflection-Lösung würde ich nicht mehr entwickeln, sowas ufert schnell aus und in Dapper gibt's das ja schon.
Und die Interface-Lösung ist sehr einfach, aber auch unflexibel und langfristig aufwändiger.

Thema: Programm zur Rechneroptimierung
Am im Forum: Smalltalk

Dem, was FZelle sagt, kann ich nur zustimmen.

Es gibt bei Windows aber ein Tool, das zuverlässig und sicher aufräumen kann und das ist Windows selber.
Schau dir die Datenträgerbereinigung an, die räumt auf, was sicher aufgeräumt werden kann.

Den Rest musst/solltest Du selber aufräumen.

Oder Du installierst regelmäßig Windows neu, sollte man sowieso immer mal wieder machen.
Das ist mehr Aufwand, aber die mit Abstand effektivste Methode, den ganzen selbst verschuldeten Müll weg zu bekommen.
Außerdem hilft das bei der Organisation der eigenen Daten.

Thema: Umrechnen in Binär Hex und Dezimal
Am im Forum: Grundlagen von C#

CrossPost: Umrechnen in Bin�r Hex und Dezimal - C# - Die Sprache - C#- & .NET Programmierung - Entwickler-Ecke

Thema: Projekt-Verschlüsselungssoftware
Am im Forum: Smalltalk

Verschlüsseln geht nicht, wie soll der PC es sonst ausführen?
Und wenn das Programm sich selbst entschlüsselt, muss der Key irgendwo stehen und den kann man dann wieder auslesen und den Code selber entschlüsseln.
Und Reflection kannst Du auch nicht verhindern, das liest nur die Metadaten jeder .NET-Assembly und ohne diese Metadaten funktioniert .NET nicht mehr.

Reflection dürfte auch weniger das Problem sein, sondern dass jemand deine Assembly dekompilieren möchte, richtig?
Auch das kannst Du nicht verhindern, aber Du kannst es erschweren, den Code zu verstehen. Dafür gibt's Obfuscation, bzw. Tools, die das anbieten.
Empfehlen kann ich da aber nichts, ich habe damit noch keine wirklichen Erfahrungen, aber wenn Du nach "Obfuscation" suchst, findest Du garantiert einige Artikel im Internet.

Thema: Template aus Basisstyle wiederverwenden
Am im Forum: GUI: WPF und XAML

Lies dich mal in die TemplateParts, damit kannst Du aus dem Code heraus einen Teil des Templates erreichen.
Ob das die bessere Option ist, sei mal dahin gestellt, aber es ist eine Option.
Im Zweifel würde ich mich aber auch für deine Lösung entscheiden, die ist offensichtlicher

Thema: Wann wann darf man eine Frage auch in einem anderen Forum stellen?
Am im Forum: Smalltalk

Achso, die Kritik, dass Du keine Antwort bekommen hast, bezog sich gar nicht auf dieses Forum? Den Teil hab ich im ersten Beitrag wohl überlesen ^^
Aber wenn's eine andere Sprache ist, weiß ich nicht, ob Du hier so viel Erfolg haben willst, der Großteil ist hier immerhin im .NET-Bereich aktiv.

Stell einfach deine Frage und schreib einen Link zum alten Thema und den Grund für den CrossPost.
Das versteht denke ich jeder, kann ja immer mal vorkommen und verscheuchen will dich auch niemand.
Es geht denke ich hauptsächlich darum, dass die Antworten auch gewertschätzt werden und dass über Foren-Grenzen hinweg keine Diskussion entstehen kann.

Thema: Wann wann darf man eine Frage auch in einem anderen Forum stellen?
Am im Forum: Smalltalk

Verbietet dir niemand, also frag halt.
Aber warum fragst Du nicht hier nochmal im selben Thema, wenn Du keine hilfreiche Antwort bekommen hast?
Oder hat dir die Antwort nicht gefallen? In diesem Fall ist die Chance groß, dass es in einem anderen Forum ähnlich laufen wird.

Thema: Performance-Verbesserungen in .NET 6
Am im Forum: Szenenews

Zitat
..., dass die Solution Organisation nicht so ist, wie sie sein sollte (bitte keine Diskussion nun)

Du möchtest keine Diskussion dazu, aber hast Du Quellen dazu? Ich will nicht diskutieren, sondern mich nur belesen ^^
Ich kenne nur deinen eher auf Übersicht ausgelegten Artikel zur Ordner-Struktur: [FAQ] Ordnerstruktur für .NET Projekte
Ob und wie ich VisualStudio durch die Solution-Organisation optimieren kann, würde mich aber sehr interessieren.

Thema: [FAQ] Das .NET Ökosystem - .NET, .NET Core, .NET Standard, NuGet und Co
Am im Forum: FAQ

Schöne Arbeit, danke dafür

Thema: Alle Methodenaufrufe protokollieren zwecks Behebung von Bugs
Am im Forum: Rund um die Programmierung

Was Du schreibst, klingt ein bisschen so, als wär euer Logging selbst geschrieben?
Wenn das so ist: Lasst es bleiben. Ich habe schon ein paar solcher Lösungen gesehen und die hatten bisher alle mehr oder weniger große Probleme, die sich teilweise nicht mal richtig beseitigen ließen und meist erst aufgefallen sind, wenn es am wenigsten passt.
Nutzt ein vorhandenes Logging-Framework, die kümmern sich auch um Performance. Serilog ist z.B. sehr beliebt, oder Microsoft.Extensions.Logging (quasi alle Logging-Frameworks unterstützen das), was in ASP.NET Core mit dabei ist. Oder log4net, ich mag's aber nicht.
Und ich würde nicht auf eine Queue verzichten. Exceptions kannst Du global abfangen und in diesem Ausnahmefall die Queue abarbeiten lassen. Die paar Fälle, wo das nicht geht, sind selten und bei z.B. einer StackOverflowException ist auch egal, dass nicht alles im Log steht, Du hast das sowieso zigfach wiederholt drin stehen.

Für z.B. Serilog und Microsofts Logging gibt's garantiert auch Erweiterungen, die an einen Logging-Server senden, entsprechende Server-Software vorausgesetzt, damit habe ich aber keine Erfahrung.
Ansonsten tut's auch eine simple ASP.NET Core API, die das entgegen nimmt und weg schreibt.


Ich persönlich würde schauen, was es bereits für Lösungen für Serilog gibt und dann ggf. die verwenden.
Alternativ setze ich die kleine ASP.NET Core API hin, den Sink für Serilog zu schreiben ist danach kaum Arbeit.

Thema: ODBC Verbindung auf MS Access 2019
Am im Forum: Datentechnologien

Such doch einfach bei NuGet nach odbc
Erstes Ergebnis.

Abgesehen davon ist Access keine Datenbank und solange Du nicht aus irgendwelchen Gründen gezwungen bist, solltest Du eine richtige Datenbank verwenden.

Thema: .Net Framework Kompatibilität
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

@Abt:
Kennst Du eine gute Übersicht von Microsoft zu diesen Zusammenhängen?
Gerade für Einsteiger kann das ja ziemlich verwirrend sein, da würde eine Übersicht helfen.

Thema: .Net Framework Kompatibilität
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Das geht nicht, steht doch in der Meldung: "ist nicht möglich"

Entweder Du gehst mit der Version runter (was bescheuert wäre) oder Du ziehst die Version hoch. Für Letzteres gibt's Doku zum migrieren.

Oder Du verwendest .NET Standard 2.0 anstelle von .NET 4.7.1, das kannst Du dann sowohl in .NET 4.7.1 als auch .NET Core 3.1 einbinden. Wie gut das mit WinForms funktioniert, weiß ich aber nicht.
Und bedenke, dass .NET Standard nicht mehr weiterentwickelt wird, das sollte man nur noch nutzen, wenn man die Kompatibilität für alte Frameworks braucht.

Besser wäre, Du nutzt überall .NET Core oder Neuer - sofern möglich.

Thema: Deklaration, Definition, Initialisierung, Public, Private, Protected, Void
Am im Forum: Grundlagen von C#

... generell das ganze Buch.

Wer Bereit ist, die 50€ auszugeben, kann auch direkt zum Nachfolger (Visual C# 2019) greifen.

Thema: Deklaration, Definition, Initialisierung, Public, Private, Protected, Void
Am im Forum: Grundlagen von C#

Zitat
Eine Initialisierung ist sowas:

Deine Beispiele sind Deklaration und Initialisierung in einem.
Richtig wäre:


string email; // Deklaration
email = "[email protected]"; //Initialisierung
Zitat
Eine Definition ist sowas wie eine Funktion, also beispielsweise das hier

"Definition" ist meines Wissens nach gar nicht genauer belegt, ich würde darunter aber alles verstehen, wo irgendetwas eindeutig "beschrieben" wird, also auch Methoden, Klassen, Variablen, völlig egal was.
"Funktionen" sind in C# aber etwas anderes, was Du gezeigt hast, ist die Definition einer Methode.
Zitat
Wann in der Praxis verwendet man public und wann kommt private zum Einsatz und

Man überlegt sich, wann man etwas public braucht, alles andere bleibt private.
Das Thema heißt Kapselung - solltest Du dir anschauen, ist ein wichtiger Bestandteil von OOP.
Zitat
warum macht man nicht alles public?

Zur Sicherheit - Du lässt ja auch nicht jeden dein Geld überweisen, das willst Du schön selbst machen und dabei kontrollieren.
Zitat
Dann gibt es noch protected, aber das scheint eine Sonderform zu sein

Keine Sonderform, aber nur bei Vererbung relevant.
Sonderformen wären "internal", "private protected" und "protected internal".
Zitat
Bei Funktionen wird wohl immer public genommen

Natürlich nicht, aber es gibt leider viele, die das machen.
Man sollte sich immer überlegen, was von außen erreichbar sein soll und was nicht.

Ich persönlich versuche immer so wenig wie möglich public zu machen, eben nur das, was ich auch brauche. Dadurch muss ich in den Methoden nicht sicherstellen, dass sie auch gefahrlos von außen benutzt werden können und ich brauche keine Probleme mit anderen Code befürchten, wenn ich sie ändere.
Zitat
Bei Funktionen kenne ich nur den Zusatz "void"

Völlig anderes Thema.
"void" meint, dass die Methode keinen Rückgabewert hat.

Thema: Wie Login-Mail deaktivieren?
Am im Forum: Wünsche und Kritik

Ja - hab's gerade nochmal getestet.
Keine Cookies = bei jedem Login eine Email

Ergibt aber auch Sinn, wie soll der Server den Browser sonst identifizieren können?
Vielleicht kann man sich aus den UserAgent-Daten eine Art ID zusammen basteln, wirklich eindeutig ist das aber nicht und damit auch nicht sicher.

Thema: Wie Login-Mail deaktivieren?
Am im Forum: Wünsche und Kritik

Die Mail sollte doch nicht so oft verschickt werden?
Soweit ich das mitbekommen habe bekommst Du die nur, wenn Du einen anderen PC oder Browser verwendest, den Du vorher noch nicht verwendet hast.
Solange das so bleibt, halte ich das auch für sehr wichtig.

Vielleicht hängt das mit (nicht gespeicherten) Cookies zusammen?

Thema: WPF Programm bleibt beim Aufruf hängen
Am im Forum: GUI: WPF und XAML

Der blaue Kreis von Windows, wenn ein Programm nicht antwortet?
Dann tust Du zu viel im UI-Thread - sollte man nicht tun.
Oder Du hast einen Deadlock, der den UI-Thread dauerhaft blockiert.

Das hat aber nicht pauschal etwas mit Debug vs. Release zu tun, zumindest nicht bei .NET.
Du hast wahrscheinlich irgendetwas, was sich im Release anders verhält und zu dem Problem führt.

Wie Du das findest, kann dir hier niemand sagen, da gibt's massig Wege.
Wenn Du es im Code oder beim Debuggen nicht identifizieren kannst, kannst Du alternativ so lange kleine Teile des Start-Prozesses raus werfen, bis es nicht mehr blockiert - was Du zuletzt raus geworfen hast, ist dann die Ursache.

Thema: Wie suche & finde ich Farb Pixel auf dem Screen?
Am im Forum: Grafik und Sound

Man kann die WinAPI (und andere) Funktionen mit C# aufrufen.
Die Technologie dafür heißt "p/invoke"
Hilfreich ist da die Website pinvoke.net.

Thema: dynamische Code evaluierung
Am im Forum: Rund um die Programmierung

Was Du mit den Predicates machen willst, geht langfristig in die Hose.
Es gibt/gab zwar ein Framework, das eine LambdaExpression als String de/serialisiert, das könntest Du dann speichern, aber wie gesagt: Das geht in die Hose ^^

Besser wäre aber, Du denkst um und beschränkst dich auf das, was mit der Datenbank geht.
Z.B. eine Art Mapping, welcher Config-Eintrag mit welchem Key/Value geprüft werden soll oder ob der Wert ein Regex-Pattern ist und so weiter.

Zitat von Abt
Prinzipiell schon, verwendet zB EF unter der Haube.

Hast Du einen Namen oder Link oder eine Quelle?
Hier steht kein Provider dafür.
Oder gibt's das nicht als eigenes Packages, sondern nur intern in EFCore?
So ein DB-Provider ist eigentlich das Einzige, was ich da noch vermissen würde.

Thema: dynamische Code evaluierung
Am im Forum: Rund um die Programmierung

Microsoft.Extensions.Configuration

Das macht das ganze mit JSON, XML, INI, what ever.
Gibt's glaub auch für die DB, dann aber nicht von Mircosoft, ein eigener DB-Provider wäre aber nicht so riesig schwer.
Damit arbeitest Du dann mit IConfiguration und das arbeitet mit Strings.

Zusätzlich gibt's noch Microsoft.Extensions.Configuration.Binder und Microsoft.Extensions.Options (mit Microsoft.Extensions.Options.ConfigurationExtensions)
Ersteres bietet die Möglichkeit, die Konfiguration auf Objekte zu mappen und Letzteres liefert eine Options-Pattern-Implementierung mit automatische Anbindung an die Konfiguration..

Die Konfiguration solltest Du in Form einer simplen Key/Value-Tabelle speicherst, zusätzlich so Infos wie eine Beschreibung oder der Typ. Bedenke aber, dass der Key auch zum Configuration-Prinzip aus den Frameworks passen muss, schwer ist das aber nicht.
Das kannst Du dann leicht anzeigen und bearbeiten, das Configuration-Framework liefert dann den Zugriff innerhalb des Programms und kann ggf. auf Objekte gemappt werden.


PS:
JimStark war wohl schneller

Thema: Sammelthema Wünsche und Bugreports myCSharp
Am im Forum: Wünsche und Kritik

Alle Links in einem neuen Tab halte ich für eine ganz schlechte Lösung.
Aber nur externe Links in einem neuen Tab sind denke ich ein guter Zwischenlösung.

Thema: Sammelthema Wünsche und Bugreports myCSharp
Am im Forum: Wünsche und Kritik

Zitat
Gewonnen hat die Argumentation, dass wir nicht immer im neuen Fenster öffnen, sondern das dem Benutzer überlassen (zB durch mittlere Maustaste).

Ich hätte es auch lieber anders :-)

Ich schließe mich deinen Kollegen an: Lieber dem Nutzer überlassen.
Warum ... keine Ahnung, vielleicht Gewohnheit.
Allerdings arbeiten sehr viele andere Websites auch so, ich halte es für klüger, ungefähr bei dem zu bleiben, was verbreitet ist.

Ich persönlich nutze aber so gut wie immer die Mitteltaste und öffne einfach alles in einem neuen Tab.
Es würde mich also nicht wirklich stören, wenn Du das änderst - ich habe so oder so nach ca. 10 Minuten rund 500 Tabs

Thema: App Status auf anderem PC
Am im Forum: Netzwerktechnologien

Oder eine gemeinsame Server-Anwendung, bei der jeder Prozess regelmäßig seinen Status hinterlegt.
So könnte jeder Prozess dort den Status anderer PCs abfragen und wenn später auch Datenaustausch nötig wird, wäre das einfacher.

Thema: Zugriff auf Klasse mittels String-Variable
Am im Forum: Grundlagen von C#

Bei einem Catch, das einfach nur irgendeinen Default zurückgibt, bekomme ich Bauchschmerzen.

Gerade beim Thema Reflection sind die Namen fest definiert, da ist nichts dynamisch. (Naja, außer man lädt/generiert zur Laufzeit, aber das ist hier nicht der Fall)
Ist ein Name falsch, dann ist er nun mal falsch und definitiv ein Fehler zur Entwicklungszeit. So ein Fehler sollte nicht geschluckt werden!
Ich persönlich arbeite daher möglichst mit nameof (Docs), dann passt der Compiler für mich auf.

Viel eher könnte man eine "TryGetValue"-Methode daraus machen und dann entsprechend reagieren, wenn der Wert nicht gefunden wird. Dann aber bitte prüfen, ob's die Property gibt und nicht mit Exceptions für den Kontrollfluss arbeiten.
Oder man lässt die Exception fliegen (kapselt sie ggf. in einer Exception mit sprechendem Namen und mehr Infos) und erfährt dann auch auf Anhieb, was das Problem war.
Konkrete Exceptions an der konkreten Position sind sehr viel leichter zu behandeln, als ein Fehler wie "irgendwo ist irgendwann ein null entstanden".

Außerdem habe ich die Erfahrung gemacht, dass solche allgemeinen ExtensionMethods früher oder später zu Chaos führen.
Bedenke, dass sie für alles gelten (object) und Du sie daher auch überall aufrufen kannst, was einerseits nervig werden und andererseits zu ungünstigen Abhängigkeiten führen kann.
Abgesehen davon ist das Ding auch nichts anderes als eine ganz normale statische Methode mit ein bisschen Compiler-Zucker und den gleichen Nachteilen, die jede statische Methode hat. Bei diesem Beispiel ist das kein Problem, sobald aber etwas spezifischere Logik dazu kommt, wird es zu einem Problem, das Du nicht mehr so einfach weg bekommst.

Das heißt, wenn es auf eine solche Reflection-Lösung hinauslaufen sollte:
Einfach eine normale private Methode in die Klasse, in der sie gebraucht wird.
Und ein sinnvolles Fehlerhandling indem z.B. geprüft wird, ob es die Property auch wirklich gibt und ein Setter da ist.

Thema: Probleme mit Registry-Abfrage von zwei Registry-Pfaden
Am im Forum: Rund um die Programmierung


var value = GetDisplayVersionOrNull("...")
    ?? GetDisplayVersionOrNull("...");

if (value == null)
{
    // ...
}
else
{
    // ...
}

Muss keine eigene Methode sein, macht das aber cleaner.

Ach und guck dir das an:
Registry.GetValue(String, String, Object) Methode (Microsoft.Win32)
Erspart dir vermutlich die eigene GetDisplayVersion-Methode.

Und Thema NullReference:

Packs in eine Variable und prüf drauf, in der eigenen Methode kein Problem.
Oder so:


var value = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey("...")?.GetValue("DisplayVersion");
Beachte das Fragezeichen vor "GetValue".