From 931ab5a86dc6ada3697954bf7cf4130f2fe11c25 Mon Sep 17 00:00:00 2001 From: keyldev Date: Sat, 6 Jun 2026 23:52:29 +0300 Subject: [PATCH] =?UTF-8?q?fix(i18n):=20refresh=20all=20localized=20bindin?= =?UTF-8?q?gs=20live=20on=20language=20switch=20-=20SetLanguage=20raised?= =?UTF-8?q?=20PropertyChanged("Item[]"),=20a=20WPF-ism=20Avalonia=20ignore?= =?UTF-8?q?s=20-=20Avalonia's=20INPC=20accessor=20re-reads=20only=20on=20P?= =?UTF-8?q?ropertyName=3D=3D"Item"=20or=20empty;=20string-keyed=20indexer?= =?UTF-8?q?=20bindings=20use=20the=20CLR=20name=20"Item",=20not=20"Item[]"?= =?UTF-8?q?=20-=20bottom=20nav=20/=20sidebar=20(persistent=20controls)=20s?= =?UTF-8?q?tayed=20stale=20until=20restart;=20pages=20only=20looked=20tran?= =?UTF-8?q?slated=20because=20they=20rebuild=20on=20navigation=20-=20raise?= =?UTF-8?q?=20PropertyChanged(string.Empty)=20=E2=80=94=20"all=20changed"?= =?UTF-8?q?=20=E2=80=94=20so=20every=20binding=20on=20Localizer.Instance?= =?UTF-8?q?=20re-reads=20instantly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/OpenIPC.Viewer.App/Services/Localizer.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/OpenIPC.Viewer.App/Services/Localizer.cs b/src/OpenIPC.Viewer.App/Services/Localizer.cs index 590996b..6983049 100644 --- a/src/OpenIPC.Viewer.App/Services/Localizer.cs +++ b/src/OpenIPC.Viewer.App/Services/Localizer.cs @@ -6,8 +6,12 @@ namespace OpenIPC.Viewer.App.Services; // Tiny ICU-free localizer. Static singleton because XAML's {Binding [Key], // Source={x:Static svc:Localizer.Instance}} pattern needs a static reference. -// PropertyChanged on "Item[]" tells all indexed bindings to re-evaluate when -// SetLanguage flips the active dict — no relaunch needed. +// SetLanguage raises PropertyChanged with an empty name ("everything changed") +// so every binding on Localizer.Instance re-reads when the active dict flips — +// no relaunch needed. Note: the WPF "Item[]" indexer convention does NOT work +// here — Avalonia's accessor only re-reads when PropertyName equals the CLR +// indexer name ("Item") or is null/empty, so persistent controls like the +// bottom nav stayed stale on "Item[]". Empty name is the reliable signal. // // EN/RU only for now; adding a third language = one more dict + one more // LangCode value. Missing keys fall back to the key itself, so adding a new @@ -41,7 +45,9 @@ public void SetLanguage(LangCode code) _ => English, }; _active = resolved; - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Item[]")); + // Empty/null name = "all properties changed"; Avalonia's INPC accessor + // re-reads on string.IsNullOrEmpty(PropertyName). "Item[]" would not match. + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(string.Empty)); } private static LangCode DetectSystem()