Oder, falls gewünscht global, mit diesem Code (siehe auch verlinkter Post):
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
Kannst du z.B. im Ctor/OnStartup deiner Application-Klasse aufrufen.
Edit:
Du hast fast die gleiche Frage schonmal gestellt und eine Antwort bekommen, wie man diese umstellt.
Vielleicht sollte man mit klarem Kopf und ausgeschlafen an die Sache rangehen
was spricht gegen das Erstellen einer Wrapper DLL wie bereits vorgeschlagen wurde?
Ich würde dies als sinnvollen und umsetzbaren Lösungsweg ansehen.
Das gelinkte Beispiel macht 1 zu 1 was du brauchst.
Hast du von der verwendeten DLL die .h und die .lib Dateien?
Was hast du schon in die Richtung versucht?
PS: Wenn die DLL eine native C/C++ DLL ist, dann macht es wenig Sinn diese als Verweis hinzuzufügen.
wenn ich das richtig sehe, hast du einen String mit als Längen-Information.
Das erste Byte stellt die maximale Länge des Strings in Bytes dar.
Das zweite Byte die tatsächliche Länge des Strings in Bytes.
Danach folgen die N Bytes des Strings (nicht verwendete Bytes sollten mit 0x00 gefüllt sein).
Du solltest schauen, was in DBB11 steht.
(Alternativ scheint es dafür schon eine Hilfsmethode in der von dir verwendeten Lib zu geben: StringEx.FromByteArray. Hier müsstest du alle Bytes, inklusive Header, in ein Byte-Array kopieren und dann die Methode aufrufen.)
die Definitionen der structs im C# entspricht nicht denen aus dem C++ Code.
Zitat
IntPtr pElement = new IntPtr(aeusere.data.ToInt32() + Marshal.SizeOf(typeof(Innere)) * i);
Einen Pointer nach Int32 umzuwandeln ist keine gute Idee. Sollte dein Programm unter 64Bit laufen wirst du eine Exception bekommen. Verwende stattdessen besser den + Operator von IntPtr.
Wo ist emxArray definiert? Mir scheint hier, dass dies a) nicht kompiliert und b) zusammengewürfelte Teile sind.
Wenn du ein Array of structs übertragen willst, kannst du dies sehr viel einfacher machen indem du im C# direkt ein Array deiner Struct als Parameter angibst. Im C++ kopierst du dann einfach die Daten via memcpy in das Array.
Da du das Array natürlich im C# vorallokieren musst, und in C++ keine Länge da ist würde ich einen weiteren in/out Parameter für die Array-Länge anlegen:
struct Innere
{
int iValue1;
int iValue2;
double dValue;
};
[DllImport(DLLPfad, CallingConvention = CallingConvention.Cdecl)]
private static extern void GetData(Innere[] data, ref int size);
int size = 0;
Innere[] data = null;
GetData(data, ref size); // Länge abrufen
data = new Innere[size]; // Array allokieren
GetData(data, ref size); // Werte direkt ins Array schreiben
Komplexer machen es nur die Kombinationen aus mehreren Buchstaben.
Täusche ich mich?
Wenn ich beim Überfliegen der Texte richtig verstanden habe, können/müssten Buchstabenkombinationen wie 'sch' oder 'ch' und Zahlen, da A-J auch 1-0 sind, separat behandelt werden. Also wird einfaches Ersetzen eines chars mit einem anderen nicht klappen.
Mit diesen zwei Spezialfällen sollte trotzdem eine recht übersichtliche Lösung zu finden sein:
- Kommt eine Zahl => 'Zahl folgt' + alle Zeichen der Zahl (hier ist die Frage wie z.B. 1,23 umgesetzt werden - ich vermute dass kein zweites 'Zahl folgt' verwendet wird)
- Kommen Zeichen, die in einer Kombination zusammengefasst sind => Kombinations-char
- Ansonsten einzelnes Zeichen mappen
du kannst den Code der an einer anderen Stelle ausgeführt werden soll in eine Methode schreiben und diese dann über die Verwendung von Delegates an einer anderen Stelle ausführen:
public static void vier_mal_wiederholen()
{
for(int i=1;i≤4;i++)
{
// hier soll der Code rein der viermal wiederholt werden soll
}
}
public static void drei_mal_wiederholen()
{
for(int i=1;i≤3;i++)
{
// hier soll der Code rein der dreimal wiederholt werden soll
}
}
public static void Test(Action action)
{
action();
MessageBox.Show("hi");
}
public static void Main()
{
Action action = vier_mal_wiederholen;
Test(action);
Test(drei_mal_wiederholen);
}
ich habe die Vermutung, dass der Schatten des Fensters bei der Berechnung der Größe mitgezählt wird, da dieser bei FormBorderStyles.None nicht gerendert wird und hier das Fenster die erwartete Größe hat.
Ich meine, dass ich genau dieses Wunschverhalten schon viele viele Male gelesen habe, das in der Form aufgrund des Fernsterverhaltens des Betriebssystem jedoch leider gar nicht möglich ist; weil eben das Window Management hier den Fokus wechselt und Du dies nicht aktiv beeinflussen kannst.
Das Löschen des Cookie Caches scheint das Problem bei mir gelöst zu haben. Bin seit gestern Nachmittag immer noch eingeloggt und bleibe es anscheinend auch nach mehreren Pausen und Reboot des Rechners.
Also geht es dir primär nicht um das Synchronisieren eines konkreten Zugriffs auf eine Instanz von List<T> (oder ähnlich) sondern du möchtest eher zwei getrennte Zugriffsebenen?
Du könntest mehrere ReaderWriterLocks oder Sync-Objekte verwenden. Die "normalen" Tasks locken immer nur Ebene 1. Wenn ein Task exklusiven Zugriff möchte lockt er ebenfalls Ebene 1 und die Threads dieses Tasks locken nur Ebene 2 um sich intern zu synchronisieren.
für mich klingt das nach ReaderWriterLock Class.
Mit dieser konnen mehrere Threads parallel aus der Liste lesen, aber immer nur ein Thread die Liste verändern.
dies entspricht nicht dem was ich beim Debuggen einer leeren Anwendung (.NET 4.8) erhalte. Vielleicht ist die Dokumentation hier nicht korrekt oder auf dem neusten Stand.
da das Loaded Event wahrscheinlich leider vor SizeToContent ausgelöst wird
Dies sollte eigentlich nicht der Fall sein.
Du könntest allerdings versuchen mit Hilfe des Dispatchers die Fixierung der Breite so zu verzögern, dass diese nach deinem Layoutprozess passiert.
Dabei musst du ggf. mit dem DispatcherPriority-Wert spielen, wobei 'Loaded' dem Loaded-Event des Fensters entpricht.
PS: Die Reihenfolge der Window-Events ist:
Initialized
Loaded
Activated
Vielleicht reicht es auch den Code im Activated-Event auszuführen.
(Activated wird allerdings jedes Mal aufgrufen, wenn das Window aktiv wird! Daher wäre es sinnvoll hier das Event wieder zu deregistrieren.)
Wenn das Bindungsziel vom Typ Brush ist kann der Converter auch einen Namen (string) aus der statischen Brushes Klasse zurückgeben. Diese wird automatisch in den passenden Brush konvertiert so wie als wäre dieser im XAML direkt gestanden.
Unsere Anwendung wechselt automatisch die Skalierung je nach Monitor, auch im laufenden Betrieb, wenn man sie zwischen den Monitoren verschiebt, sobald du
leider konnte ich auf die schnelle auch keine Dokumentation zu der genauen Bedeutung von ILONLY finden. Nachdem ich einige DLLs von uns mit corflags.exe angeschaut habe, gehe ich davon aus, dass das Flag bedeutet, dass kein unmanaged code vorhanden ist und nichts mit 32/64/AnyCPU an sich zu tun hat.
Bei einer unserer Mix-Mode DLLs ist ILONLY 0 und ILSpy gibt folgende Info aus:
"This assembly contains unmanaged code."
Wieso erstellst du nicht ein neues UserControl das die Text- und ListBox enthält und dieses Control auf die "Datenbasis" zugreift? Damit kannst du die Daten an dieses Control binden und dann auch mehrfach verwenden.