Mein Problem besteht darin, dass der Datenkontext für das Dialogfeld und sein DataGrid zwar ordnungsgemäß mit der Liste in einer ObservableCollection gefüllt zu sein scheint und sogar eine ausgewählte Zeile registriert, das DataGrid selbst jedoch nie sichtbar ist. Ich mache viele der gleichen Dinge wie eine frühere App, der größte Unterschied besteht darin, dass sich das DataGrid im Hauptfenster und nicht in einem Dialog befand.
Als mechanische Zusammenfassung wird durch Klicken auf die Schaltfläche im Hauptfenster das Hauptansichtsmodell angewiesen, eine Nachricht an den Code-Behind des Hauptfensters zu senden, um den Dialog zu öffnen. Der Datenkontext des Dialogs wird mit den vom Hauptansichtsmodell empfangenen Übersetzungen initialisiert, das die Liste nach dem Laden aus der Datei beibehält. Der Dialog wird angewiesen, die Sprachspalten in seinem DataGrid zu füllen, und wird dann geöffnet. Sobald der Dialog geschlossen ist, hört das Hauptansichtsmodell die Antwort des Code-Behinds, die die benötigten Daten enthält.
Verwendete Pakete:

Translations.json:
Code: Select all
[
{
"Key": "LangOrder",
"Xl8ns": [ "en-US", "fr-FR", "es-ES", "de-DE", "it-IT" ]
},
{
"Key": "LangNames",
"Xl8ns": [ "English", "Français", "Español", "Deutsch", "Italiano" ]
},
{
"Key": "AccumulationArea",
"Xl8ns": [ "Accumulation Area", "Zone d'accumulation", "Zona de acumulación", "Beschleunigungsbereich", "Area di accumulo" ]
},
{
"Key": "Color",
"Xl8ns": [ "Color", "Couleur", "Color", "Farbe", "Colore" ]
},
{
"Key": "Quality",
"Xl8ns": [ "Quality", "Qualité", "Calidad", "Qualität", "Qualità" ]
}
]
Code: Select all
Code: Select all
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
WeakReferenceMessenger.Default.Register(this, OpenPickLanguageKeyDialog());
}
private static MessageHandler OpenPickLanguageKeyDialog() {
return static (w, m) => {
var dlgVM = new PickLanguageKeyResultVM(m.Translations, m.CurrentKey);
var dialog = new TranslationsGridDlg {
Title = "Pick Language Key",
DataContext = dlgVM
};
dialog.InitLanguageColumns(dlgVM.Translations[0]);
// Show dialog window and reply with returned PickLanguageKeyResultVM or null when the dialog is closed
m.Reply(dialog.ShowDialog(w));
};
}
}
Code: Select all
public partial class MainWindowViewModel : ViewModelBase {
[ObservableProperty]
private string _pickedLangKey = "PickSomething";
private List _translations = [];
public MainWindowViewModel() {
var transJSON = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Assets\Translations.json"));
_translations = JsonConvert.DeserializeObject(transJSON);
}
[RelayCommand]
private async Task PickLanguageKeyAsync() {
var langKeyPick = await WeakReferenceMessenger.Default.Send(new PickLanguageKeyMessage(_translations, PickedLangKey));
if (langKeyPick != null) {
PickedLangKey = langKeyPick.SelectedTranslation == null ? "NoSelection" : langKeyPick.SelectedTranslation.Key;
} else {
PickedLangKey = "FAIL";
}
}
}
Code: Select all
public partial class PickLanguageKeyResultVM : ObservableRecipient {
public ObservableCollection Translations { get; set; } = [];
[ObservableProperty]
private TranslationVM? _selectedTranslation;
public PickLanguageKeyResultVM(List translations, string currentKey) {
var loadedLanguages = translations.First().Translations;
Translations.Clear();
foreach (var entry in translations) {
if (entry.Key != Constants.KEY_LANGUAGE_ORDER) {
var trans = new TranslationVM {
Key = entry.Key
};
for (var l = 0; l < entry.Translations.Count; l++) {
trans.LangVals.Add(new LanguageValueVM {
Language = loadedLanguages[l],
Value = entry.Translations[l]
});
}
Translations.Add(trans);
}
}
SelectedTranslation = Translations.FirstOrDefault(t => t.Key == currentKey.Trim());
if (SelectedTranslation == null) {
SelectedTranslation = Translations[2]; // Color
}
}
[RelayCommand]
public void PickKey() {
WeakReferenceMessenger.Default.Send(new PickLanguageKeyClosedMessage(this));
}
[RelayCommand]
public void CancelPick() {
WeakReferenceMessenger.Default.Send(new PickLanguageKeyClosedMessage(null));
}
}
public class PickLanguageKeyMessage(List translations, string currentKey) : AsyncRequestMessage {
public string CurrentKey { get; } = currentKey;
public List Translations { get; set; } = translations;
}
public class PickLanguageKeyClosedMessage(PickLanguageKeyResultVM? userResult) {
public PickLanguageKeyResultVM? UserResult { get; } = userResult;
}
Code: Select all
Code: Select all
public partial class TranslationsGridDlg : Window {
public TranslationsGridDlg() {
InitializeComponent();
WeakReferenceMessenger.Default.Register(
this, static (w, m) => w.Close(m.UserResult));
}
public void InitLanguageColumns(TranslationVM topEntry) {
for (var li = 0; li < topEntry.LangVals.Count; li++) {
var column = new DataGridTextColumn {
Header = topEntry.LangVals[li].Language,
Binding = new Binding($"LangVals[{li}].Value")
};
dtgTranslations.Columns.Add(column);
}
}
}
Code: Select all
[DataContract]
public class TranslationKey {
[DataMember]
public string Key { get; set; } = Constants.KEY_LANGUAGE_ORDER;
[DataMember]
[JsonProperty("Xl8ns")] // Save some JSON file space
public List Translations { get; set; } = [];
}
Code: Select all
[DataContract]
public class TranslationVM {
[DataMember]
public string Key { get; set; } = string.Empty;
[DataMember]
public List LangVals { get; set; } = [];
public List GetLanguagesOrder() {
var allLanguages = new List();
foreach (var langVal in LangVals) {
allLanguages.Add(langVal.Language);
}
return allLanguages;
}
public List GetValuesList() {
var allTranslations = new List();
foreach (var langVal in LangVals) {
allTranslations.Add(langVal.Value);
}
return allTranslations;
}
}
[DataContract]
public class LanguageValueVM : ViewModelBase {
[DataMember]
public string Language { get; set; }
[DataMember]
public string Value { get; set; }
}
Code: Select all
public class Constants {
public const string KEY_LANGUAGE_ORDER = "LangOrder";
public const string KEY_LANGUAGE_NAMES = "LangNames";
public const string LANGUAGE_ENGLISH = "en-US";
public const string LANGUAGE_FRENCH = "fr-FR";
public const string LANGUAGE_SPANISH = "es-ES";
public const string LANGUAGE_GERMAN = "de-DE";
public const string LANGUAGE_ITALIAN = "it-IT";
}
Mobile version