public MainWindowViewModel(Canvas fontCanvas, Canvas rectCanvas, FontFamily defaultFontFamily) { CultureResources.EnumerateAvailableCultures(); Languages = CultureResources.AvailableCultures.Select(culture => new Language(culture)).ToList(); var currentLanguage = Languages.Find(l => l.Culture.TwoLetterISOLanguageName == Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName); if (currentLanguage == null) { currentLanguage = Languages.Find(l => l.Culture == CultureResources.AvailableCultures[0]); } SelectedLanguage = currentLanguage; FontWeightList = LocalizedFontWeights.All; this.ObservableForProperty(x => x.SelectedLanguage) .Subscribe(lang => CultureResources.ChangeCulture(lang.Value.Culture)); FontGenerator = new RS2014FontGenerator(fontCanvas, rectCanvas); FontCanvas = fontCanvas; DefaultFontFamily = defaultFontFamily; FontList = Fonts.SystemFontFamilies.OrderBy(x => x.Source).ToList(); LoadProgramState(); WindowTitle = ProgramName; var thisAsm = Assembly.GetExecutingAssembly(); ProgramVersion = thisAsm.GetName().Version.ToString(); CreateReactiveCommands(); this.WhenAnyValue(x => x.UseDarkTheme) .Subscribe(dt => { string theme = dt ? "Dark" : "Light"; ThemeManager.Current.ChangeTheme(Application.Current, theme + ".Steel"); }); // Generate font after a delay when font size, glyph margin or spacing is changed this.WhenAnyValue( x => x.SelectedFontSize, x => x.SelectedKanjiFontSize, x => x.GlyphHorizontalMargin, x => x.SpacingAdjustment) .Where(_ => CanGenerate) // Don't do anything if generation is currently disabled .Throttle(TimeSpan.FromMilliseconds(650), RxApp.MainThreadScheduler) .DistinctUntilChanged() .Select(_ => Unit.Default) .InvokeCommand(GenerateFont); // Generate font immediately when font family or weight or "accurate inner rects" is changed this.WhenAnyValue( x => x.UseAccurateInnerRects, x => x.SelectedFont, x => x.SelectedFontWeight) .DistinctUntilChanged() .Select(_ => Unit.Default) .InvokeCommand(GenerateFont); }