/// <summary> /// Creates or updates collection /// </summary> /// <param name="collectionName"></param> /// <param name="categoryName"></param> public void SetCollection(string collectionName, string categoryName) { lock (Lock) { // Get the localization collection. If it does not exist, create it first var localizationCategory = LocalizationCategories.FirstOrDefault(x => x.Name.ToLower() == categoryName.ToLower()); if (localizationCategory == null) { localizationCategory = new LocalizationCategory { Name = categoryName }; Provider.InsertOrUpdateLocalizationCategory(localizationCategory); LocalizationCategories = Provider.LoadLocalizationCategories(); localizationCategory = LocalizationCategories.FirstOrDefault(x => x.Name.ToLower() == categoryName.ToLower()); } if (localizationCategory == null) { return; } var collection = LocalizationCollections.FirstOrDefault(x => x.Name.ToLower() == collectionName.ToLower()) ?? new LocalizationCollection { LocalizationCategoryId = localizationCategory.Id }; collection.Name = collectionName; Provider.InsertOrUpdateLocalizationCollection(collection); LocalizationCollections = Provider.LoadLocalizationCollections(); } }
private bool CanSaveLocalization() { if (!LocalizationCategories.Any()) { return(false); } int numChecked = 0; if (ShowGerman) { numChecked++; } if (ShowRussian) { numChecked++; } if (ShowPolish) { numChecked++; } if (ShowFrench) { numChecked++; } if (ShowSpanish) { numChecked++; } if (numChecked == 1) { return(true); } return(false); }
private void LoadLocalization() { OpenFileDialog openFileDialog = new OpenFileDialog() { Title = "Select [lang].xaml file", Filter = "Xaml files|*.xaml" }; if (openFileDialog.ShowDialog() == true) { var fname = openFileDialog.FileName; var basename = Path.GetFileNameWithoutExtension(fname); if (!LocalizedString.Languages.Contains(basename, StringComparer.InvariantCultureIgnoreCase)) { MessageBox.Show("Filename must be XXX.xaml, with XXX being your language code. The file selected does not match a supported language."); return; } //Wipe existing strings for that lang foreach (var cat in LocalizationCategories) { foreach (var ls in cat.LocalizedStringsForSection) { switch (basename) { case "rus": ls.RUS = null; break; case "deu": ls.DEU = null; break; case "pol": ls.POL = null; break; case "fra": ls.FRA = null; break; case "esn": ls.ESN = null; break; case "bra": ls.BRA = null; break; } } } //Load lang from file var dict = new Dictionary <string, string>(); dict[basename] = File.ReadAllText(fname); parseLocalizations(LocalizationCategories.ToList(), dict); MessageBox.Show("Loaded localization for " + basename + "."); } }
public void OnSelectedBranchChanged() { if (oldBranch != null) { if (SelectedBranch != null) { LoadLocalizations(SelectedBranch); oldBranch = SelectedBranch; } else { LocalizationCategories.ClearEx(); LocalizedTips.ClearEx(); dynamicHelpLocalizations.Clear(); } } }
/// <summary> /// Creates or updates collection /// </summary> /// <param name="collecitonName"></param> /// <param name="categoryId"></param> public void SetCollection(string collecitonName, int categoryId) { lock (Lock) { var localizationCategory = LocalizationCategories.FirstOrDefault(x => x.Id == categoryId); if (localizationCategory == null) { return; } Provider.InsertOrUpdateLocalizationCollection(new LocalizationCollection { LocalizationCategoryId = localizationCategory.Id, Name = collecitonName }); LocalizationCollections = Provider.LoadLocalizationCollections(); } }
/// <summary> /// Returns all localization categories /// </summary> /// <returns></returns> public List <LocalizationCategory> GetAllCategories() { return(LocalizationCategories.ToList()); }
/// <summary> /// Returns localization category /// </summary> /// <param name="category"></param> /// <returns></returns> public LocalizationCategory GetCategory(string category) { return(LocalizationCategories.FirstOrDefault(x => x.Name.ToLower() == category.ToLower())); }
/// <summary> /// Sets new translation for the provided key and language (or current culture language if not provided) /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="collection"></param> /// <param name="category"></param> /// <param name="culture"></param> public void Set(string key, string value, string collection, string category, CultureInfo culture = null) { lock (Lock) { // Get the localization key Id. If it does not exist, create it first var localizationKey = LocalizationKeys.FirstOrDefault(x => x.Name.ToLower() == key.ToLower()); if (localizationKey == null) { localizationKey = new LocalizationKey { Name = key }; Provider.InsertLocalizationKey(localizationKey); LocalizationKeys = Provider.LoadLocalizationKeys(); localizationKey = LocalizationKeys.FirstOrDefault(x => x.Name.ToLower() == key.ToLower()); } if (localizationKey == null) { return; } // Get the localization language. If it does not exist, create it first var langName = GetLanguageNameFromCulture(culture).ToLower(); var langDisplayName = GetLanguageDisplayNameFromCulture(culture); var localizationLanguage = LocalizationLanguages.FirstOrDefault(x => x.Name.ToLower() == GetLanguageNameFromCulture(culture).ToLower()); if (localizationLanguage == null) { localizationLanguage = new LocalizationLanguage { Name = langName, Value = langDisplayName }; Provider.InsertLocalizationLanguage(localizationLanguage); LocalizationLanguages = Provider.LoadLocalizationLanguages(); localizationLanguage = LocalizationLanguages.FirstOrDefault(x => x.Name.ToLower() == GetLanguageNameFromCulture(culture).ToLower()); } if (localizationLanguage == null) { return; } // Get the localization collection. If it does not exist, create it first var localizationCategory = LocalizationCategories.FirstOrDefault(x => x.Name.ToLower() == category.ToLower()); if (localizationCategory == null) { localizationCategory = new LocalizationCategory { Name = category }; Provider.InsertOrUpdateLocalizationCategory(localizationCategory); LocalizationCategories = Provider.LoadLocalizationCategories(); localizationCategory = LocalizationCategories.FirstOrDefault(x => x.Name.ToLower() == category.ToLower()); } if (localizationCategory == null) { return; } // Get the localization collection. If it does not exist, create it first var localizationCollection = LocalizationCollections.FirstOrDefault(x => x.Name.ToLower() == collection.ToLower() && x.LocalizationCategoryId == localizationCategory.Id); if (localizationCollection == null) { localizationCollection = new LocalizationCollection { Name = collection, LocalizationCategoryId = localizationCategory.Id }; Provider.InsertOrUpdateLocalizationCollection(localizationCollection); LocalizationCollections = Provider.LoadLocalizationCollections(); localizationCollection = LocalizationCollections.FirstOrDefault(x => x.Name.ToLower() == collection.ToLower() && x.LocalizationCategoryId == localizationCategory.Id); } if (localizationCollection == null) { return; } localizationCollection.LocalizationCategory = localizationCategory; localizationCollection.LocalizationCategoryId = localizationCategory.Id; // Don't check the collection since only one combination of key and language is allowed across collections var entry = LocalizationEntries.FirstOrDefault(x => x.LocalizationKeyId == localizationKey.Id && x.LocalizationLanguageId == localizationLanguage.Id); if (entry == null) { // Create entry = new LocalizationEntry { Value = value, LocalizationCollectionId = localizationCollection.Id, LocalizationKeyId = localizationKey.Id, LocalizationLanguageId = localizationLanguage.Id, CreatedOn = DateTime.UtcNow, UpdatedOn = DateTime.UtcNow }; Provider.InsertLocalizationEntry(entry); LocalizationEntries = Provider.LoadLocalizationEntries(); } } }
private void Find_Clicked(object sender, RoutedEventArgs e) { int indexOfCurrentCategory = SelectedCategory != null?LocalizationCategories.IndexOf(SelectedCategory) : 0; Debug.WriteLine("Current cat index: " + indexOfCurrentCategory); int numCategories = LocalizationCategories.Count(); //might need to +1 this string searchTerm = SearchText.ToLower(); if (string.IsNullOrEmpty(searchTerm)) { return; } LocalizedString itemToHighlight = null; LocalizationCategory catToHighlight = null; for (int i = 0; i < numCategories; i++) { bool found = false; LocalizationCategory cat = LocalizationCategories[(i + indexOfCurrentCategory) % LocalizationCategories.Count()]; int startSearchIndex = 0; int numToSearch = cat.LocalizedStringsForSection.Count(); if (i == 0 && cat == SelectedCategory && SelectedDataGridItem != null) { startSearchIndex = cat.LocalizedStringsForSection.IndexOf(SelectedDataGridItem) + 1; numToSearch -= startSearchIndex; } Debug.WriteLine(cat.CategoryName); for (int j = 0; j < numToSearch; j++) { var ls = cat.LocalizedStringsForSection[(j + startSearchIndex) % cat.LocalizedStringsForSection.Count]; //Key if (ls.key.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)) { //found found = true; itemToHighlight = ls; catToHighlight = cat; break; } //English if (ls.INT.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)) { //found found = true; itemToHighlight = ls; catToHighlight = cat; break; } //German if (ShowGerman && ls.DEU != null && ls.DEU.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)) { //found found = true; itemToHighlight = ls; catToHighlight = cat; break; } //Russian if (ShowRussian && ls.RUS != null && ls.RUS.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)) { //found found = true; itemToHighlight = ls; catToHighlight = cat; break; } //Polish if (ShowPolish && ls.POL != null && ls.POL.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)) { //found found = true; itemToHighlight = ls; catToHighlight = cat; break; } //French if (ShowFrench && ls.FRA != null && ls.FRA.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)) { //found found = true; itemToHighlight = ls; catToHighlight = cat; break; } //Spanish if (ShowSpanish && ls.ESN != null && ls.ESN.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)) { //found found = true; itemToHighlight = ls; catToHighlight = cat; break; } } if (found) { break; } } if (itemToHighlight == null) { SystemSounds.Beep.Play(); } else { SelectedCategory = catToHighlight; SelectedDataGridItem = itemToHighlight; DataGridTable.ScrollIntoView(SelectedDataGridItem); } }
private void LoadLocalizations(string branch = null) { BackgroundWorker bw = new BackgroundWorker(); bw.DoWork += (x, y) => { if (!LocalizationBranches.Any()) { var ghclient = new GitHubClient(new ProductHeaderValue(@"ME3TweaksModManager")); try { var branches = ghclient.Repository.Branch.GetAll("ME3Tweaks", "ME3TweaksModManager").Result; var locbranches = branches.Where(x => x.Name.Contains("master") || x.Name.Contains("-localization")); System.Windows.Application.Current.Dispatcher.Invoke(delegate { LocalizationBranches.ReplaceAll(locbranches.Select(x => x.Name)); }); } catch (Exception e) { System.Windows.Application.Current.Dispatcher.Invoke(delegate { MessageBox.Show("Error getting list of localization branches: " + e.Message); }); return; } } if (LocalizationBranches.Any()) { if (branch == null) { branch = LocalizationBranches.First(); SelectedBranch = branch; oldBranch = branch; } } else { System.Windows.Application.Current.Dispatcher.Invoke(delegate { MessageBox.Show("Could not find any branches on ME3TweaksModManager repo containing name 'localization'"); }); return; } var dictionaries = new Dictionary <string, string>(); string endpoint = $"https://raw.githubusercontent.com/ME3Tweaks/ME3TweaksModManager/{branch}/MassEffectModManagerCore/modmanager/localizations/"; //make dynamic, maybe with octokit. WebClient client = new WebClient(); foreach (var lang in LocalizedString.Languages) { var url = endpoint + lang + ".xaml"; var dict = client.DownloadStringAwareOfEncoding(url); dictionaries[lang] = dict; } //Parse INT. int currentLine = 3; //Skip header. LocalizationCategory cat = null; int numBlankLines = 0; List <LocalizationCategory> categories = new List <LocalizationCategory>(); var intLines = Regex.Split(dictionaries["int"], "\r\n|\r|\n"); for (int i = 3; i < intLines.Length - 2; i++) { var line = intLines[i].Trim(); if (string.IsNullOrWhiteSpace(line)) { numBlankLines++; continue; } if (line.StartsWith("<!--") && line.EndsWith("-->")) { //Comment - parse line = line.Substring(4); line = line.Substring(0, line.Length - 3); line = line.Trim(); if (numBlankLines > 0 || cat == null) { //New category? if (cat != null) { categories.Add(cat); } cat = new LocalizationCategory() { CategoryName = line }; } //notes for previous item? var prevItem = cat.LocalizedStringsForSection.LastOrDefault(); if (prevItem != null) { prevItem.notes = line; } //Debug.WriteLine(line); //New Category //line = line. continue; } numBlankLines = 0; var lineInfo = extractInfo(line); LocalizedString ls = new LocalizedString() { key = lineInfo.key, preservewhitespace = lineInfo.preserveWhitespace, INT = lineInfo.text }; if (lineInfo.key == null) { Debugger.Break(); } if (ls.INT == null) { Debugger.Break(); } cat.LocalizedStringsForSection.Add(ls); } if (cat != null) { categories.Add(cat); } parseLocalizations(categories, dictionaries); y.Result = categories; //TIPS SERVICE string tipsEndpoint = "https://me3tweaks.com/modmanager/services/tipsservice"; string contents; using var wc = new System.Net.WebClient(); var tipsJson = wc.DownloadString(tipsEndpoint); var jsonObj = JsonConvert.DeserializeObject <Dictionary <string, List <string> > >(tipsJson); var langs = LocalizedString.Languages.Where(x => x != "int"); var locTips = new List <LocalizedString>(); for (int i = 0; i < jsonObj["int"].Count; i++) { LocalizedString ls = new LocalizedString() { INT = jsonObj["int"][i] }; foreach (var lang in langs) { if (jsonObj[lang].Count <= i) { continue; //skip } switch (lang) { case "rus": ls.RUS = jsonObj["rus"][i]; break; case "deu": ls.DEU = jsonObj["deu"][i]; break; case "pol": ls.POL = jsonObj["pol"][i]; break; case "fra": ls.FRA = jsonObj["fra"][i]; break; case "esn": ls.ESN = jsonObj["esn"][i]; break; } } locTips.Add(ls); } System.Windows.Application.Current.Dispatcher.Invoke(delegate { LocalizedTips.ReplaceAll(locTips); }); //DYNAMIC HELP endpoint = $"https://raw.githubusercontent.com/ME3Tweaks/ME3TweaksModManager/{branch}/MassEffectModManagerCore/staticfiles/dynamichelp/latesthelp-localized.xml"; var dynamicHelpXml = wc.DownloadString(endpoint); XDocument doc = XDocument.Parse(dynamicHelpXml); var intxml = doc.XPathSelectElement("/localizations/helpmenu[@lang='int']"); dynamicHelpLocalizations["int"] = intxml.ToString(); Debug.WriteLine(doc.ToString()); foreach (var lang in langs) { var langxml = doc.XPathSelectElement($"/localizations/helpmenu[@lang='{lang}']"); if (langxml != null) { dynamicHelpLocalizations[lang] = langxml.ToString(); } } /* * var langs = LocalizedString.Languages.Where(x => x != "int"); * var locTips = new List<LocalizedString>(); * for (int i = 0; i < jsonObj["int"].Count; i++) * { * LocalizedString ls = new LocalizedString() * { * INT = jsonObj["int"][i] * }; * foreach (var lang in langs) * { * if (jsonObj[lang].Count <= i) continue; //skip * switch (lang) * { * case "rus": * ls.RUS = jsonObj["rus"][i]; * break; * case "deu": * ls.DEU = jsonObj["deu"][i]; * break; * case "pol": * ls.POL = jsonObj["pol"][i]; * break; * case "fra": * ls.FRA = jsonObj["fra"][i]; * break; * case "esn": * ls.ESN = jsonObj["esn"][i]; * break; * } * } * locTips.Add(ls); * } */ System.Windows.Application.Current.Dispatcher.Invoke(delegate { intViewer.Text = intxml.ToString(); LocalizedTips.ReplaceAll(locTips); }); }; bw.RunWorkerCompleted += (a, b) => { if (b.Error == null && b.Result is List <LocalizationCategory> categories) { LocalizationCategories.ReplaceAll(categories); } }; bw.RunWorkerAsync(); }
private void LoadLocalizations(string branch = null) { BackgroundWorker bw = new BackgroundWorker(); bw.DoWork += (x, y) => { if (!LocalizationBranches.Any()) { PleaseWaitString = "Fetching remote localization branches"; var ghclient = new GitHubClient(new ProductHeaderValue(@"ME3TweaksModManager")); try { var branches = ghclient.Repository.Branch.GetAll("ME3Tweaks", "ME3TweaksModManager").Result; var locbranches = branches.Where(x => /*x.Name.Contains("master") ||*/ x.Name.Contains("-localization")); System.Windows.Application.Current.Dispatcher.Invoke(delegate { LocalizationBranches.ReplaceAll(locbranches.Select(x => x.Name).OrderByDescending(x => x)); }); } catch (Exception e) { System.Windows.Application.Current.Dispatcher.Invoke(delegate { MessageBox.Show("Error getting list of localization branches: " + e.Message); }); return; } } string oldBuildBranch = null; if (LocalizationBranches.Any()) { if (branch == null) { branch = LocalizationBranches.First(); SelectedBranch = branch; oldBranch = branch; if (LocalizationBranches.Count() > 1) { oldBuildBranch = LocalizationBranches[1]; } } } else { System.Windows.Application.Current.Dispatcher.Invoke(delegate { MessageBox.Show("Could not find any branches on ME3TweaksModManager repo containing name 'localization'"); }); return; } var dictionaries = new Dictionary <string, string>(); string endpoint = $"https://raw.githubusercontent.com/ME3Tweaks/ME3TweaksModManager/{branch}/MassEffectModManagerCore/modmanager/localizations/"; //make dynamic, maybe with octokit. WebClient client = new WebClient(); foreach (var lang in LocalizedString.Languages) { PleaseWaitString = $"Fetching {branch} {lang}"; var url = endpoint + lang + ".xaml"; var dict = client.DownloadStringAwareOfEncoding(url); dictionaries[lang] = dict; } if (oldBuildBranch != null) { PleaseWaitString = $"Fetching {oldBuildBranch} int"; endpoint = $"https://raw.githubusercontent.com/ME3Tweaks/ME3TweaksModManager/{oldBuildBranch}/MassEffectModManagerCore/modmanager/localizations/"; //make dynamic, maybe with octokit. var url = endpoint + "int.xaml"; var dict = client.DownloadStringAwareOfEncoding(url); dictionaries["int-prev"] = dict; } PleaseWaitString = $"Parsing main strings"; Dictionary <string, string> oldStuff = new Dictionary <string, string>(); if (dictionaries.TryGetValue("int-prev", out var oldStrXml)) { XDocument oldBuildDoc = XDocument.Parse(oldStrXml); XNamespace system = "clr-namespace:System;assembly=System.Runtime"; XNamespace xk = "http://schemas.microsoft.com/winfx/2006/xaml"; var lstrings = oldBuildDoc.Root.Descendants(system + "String").ToList(); foreach (var lstring in lstrings) { oldStuff[lstring.Attribute(xk + "Key").Value] = lstring.Value; } } //Parse INT. int currentLine = 3; //Skip header. LocalizationCategory cat = null; int numBlankLines = 0; List <LocalizationCategory> categories = new List <LocalizationCategory>(); var intLines = Regex.Split(dictionaries["int"], "\r\n|\r|\n"); for (int i = 3; i < intLines.Length - 2; i++) { var line = intLines[i].Trim(); if (string.IsNullOrWhiteSpace(line)) { numBlankLines++; continue; } if (line.StartsWith("<!--") && line.EndsWith("-->")) { //Comment - parse line = line.Substring(4); line = line.Substring(0, line.Length - 3); line = line.Trim(); if (numBlankLines > 0 || cat == null) { //New category? if (cat != null) { categories.Add(cat); } cat = new LocalizationCategory() { CategoryName = line }; } //notes for previous item? var prevItem = cat.LocalizedStringsForSection.LastOrDefault(); if (prevItem != null) { prevItem.notes = line; } //Debug.WriteLine(line); //New Category //line = line. continue; } numBlankLines = 0; var lineInfo = extractInfo(line); LocalizedString ls = new LocalizedString() { key = lineInfo.key, preservewhitespace = lineInfo.preserveWhitespace, INT = lineInfo.text }; if (oldStuff.TryGetValue(lineInfo.key, out var oldString)) { var oldValue = new XText(oldString).ToString(); var newValue = new XText(lineInfo.text).ToString(); XDocument newV = XDocument.Parse("<text>" + lineInfo.text + "</text>"); if (oldString != newV.Root.Value) { if (ls.key == "string_modEndorsed") { Debugger.Break(); } Debug.WriteLine("Changed: " + ls.key); Debug.WriteLine(" OLD: " + oldString); Debug.WriteLine(" NEW: " + lineInfo.text); ls.ChangedFromPrevious = true; } } else if (oldStuff.Any()) { Debug.WriteLine("New: " + ls.key); ls.ChangedFromPrevious = true; } if (lineInfo.key == null) { Debugger.Break(); } if (ls.INT == null) { Debugger.Break(); } cat.LocalizedStringsForSection.Add(ls); } if (cat != null) { categories.Add(cat); } parseLocalizations(categories, dictionaries); y.Result = categories; //TIPS SERVICE PleaseWaitString = $"Fetching Tips Service"; string tipsEndpoint = "https://me3tweaks.com/modmanager/services/tipsservice"; string contents; var wc = new System.Net.WebClient(); var tipsJson = wc.DownloadString(tipsEndpoint); var jsonObj = JsonConvert.DeserializeObject <Dictionary <string, List <string> > >(tipsJson); var langs = LocalizedString.Languages.Where(x => x != "int"); var locTips = new List <LocalizedString>(); for (int i = 0; i < jsonObj["int"].Count; i++) { LocalizedString ls = new LocalizedString() { INT = jsonObj["int"][i] }; foreach (var lang in langs) { if (jsonObj[lang].Count <= i) { continue; //skip } switch (lang) { case "rus": ls.RUS = jsonObj["rus"][i]; break; case "deu": ls.DEU = jsonObj["deu"][i]; break; case "pol": ls.POL = jsonObj["pol"][i]; break; case "fra": ls.FRA = jsonObj["fra"][i]; break; case "esn": ls.ESN = jsonObj["esn"][i]; break; case "bra": ls.BRA = jsonObj["bra"][i]; break; } } locTips.Add(ls); } System.Windows.Application.Current.Dispatcher.Invoke(delegate { LocalizedTips.ReplaceAll(locTips); }); //DYNAMIC HELP PleaseWaitString = $"Fetching Dynamic Help"; endpoint = $"https://raw.githubusercontent.com/ME3Tweaks/ME3TweaksModManager/{branch}/MassEffectModManagerCore/staticfiles/dynamichelp/latesthelp-localized.xml"; var dynamicHelpXml = wc.DownloadString(endpoint); XDocument doc = XDocument.Parse(dynamicHelpXml); var intxml = doc.XPathSelectElement("/localizations/helpmenu[@lang='int']"); dynamicHelpLocalizations["int"] = intxml.ToString(); //Debug.WriteLine(doc.ToString()); foreach (var lang in langs) { var langxml = doc.XPathSelectElement($"/localizations/helpmenu[@lang='{lang}']"); if (langxml != null) { dynamicHelpLocalizations[lang] = langxml.ToString(); } } // TUTORIAL SERVICE PleaseWaitString = $"Fetching Tutorial Service"; string tutorialEndpoint = "https://me3tweaks.com/modmanager/services/tutorialservice"; wc.Dispose(); wc = new System.Net.WebClient(); var tutorialJson = wc.DownloadString(tutorialEndpoint); var TSjsonObj = JsonConvert.DeserializeObject <List <Dictionary <string, string> > >(tutorialJson); langs = LocalizedString.Languages.Where(x => x != "int"); var locTutorial = new List <LocalizedString>(); for (int i = 0; i < TSjsonObj.Count; i++) { LocalizedString ls = new LocalizedString() { INT = TSjsonObj[i]["lang_int"] }; foreach (var lang in langs) { switch (lang) { case "rus": ls.RUS = TSjsonObj[i]["lang_rus"]; break; case "deu": ls.DEU = TSjsonObj[i]["lang_deu"]; break; case "pol": ls.POL = TSjsonObj[i]["lang_pol"]; break; case "fra": ls.FRA = TSjsonObj[i]["lang_fra"]; break; case "esn": ls.ESN = TSjsonObj[i]["lang_esn"]; break; case "bra": ls.BRA = TSjsonObj[i]["lang_bra"]; break; } } locTutorial.Add(ls); } PleaseWaitString = ""; System.Windows.Application.Current.Dispatcher.Invoke(delegate { LocalizedTutorialService.ReplaceAll(locTutorial); intViewer.Text = intxml.ToString(); }); }; bw.RunWorkerCompleted += (a, b) => { if (b.Error == null && b.Result is List <LocalizationCategory> categories) { LoadingVisibility = Visibility.Collapsed; LocalizationCategories.ReplaceAll(categories); } }; bw.RunWorkerAsync(); }