diff --git a/README.md b/README.md index e7da2e93e7..f38a34fcf8 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ Many tools are available. - Generators - Hash (MD5, SHA1, SHA256, SHA512) - UUID 1 and 4 + - Lorem Ipsum - Text - Inspector & Case Converter - Regex Tester @@ -84,6 +85,7 @@ Here is the list of tool name you can use: - `base64` - Base64 Encoder/Decoder - `hash` - Hash Generator - `uuid` - UUID Generator +- `loremipsum` - Lorem Ipsum Generator - `jsonformat` Json Formatter - `jsonyaml` - Json <> Yaml - `jwt` - JWT Decoder diff --git a/THIRD-PARTY-NOTICES.md b/THIRD-PARTY-NOTICES.md index 3d4a4de31b..e0e3f0f314 100644 --- a/THIRD-PARTY-NOTICES.md +++ b/THIRD-PARTY-NOTICES.md @@ -14,6 +14,7 @@ This project incorporates components from the projects listed below. The origina 10. Markdig (https://github.com/xoofx/markdig) 11. github-markdown-css (https://github.com/sindresorhus/github-markdown-css) 12. Efficient Compression Tool (https://github.com/fhanau/Efficient-Compression-Tool) +13. NLipsum (https://github.com/alexcpendleton/NLipsum) Newtonsoft.Json NOTICES AND INFORMATION BEGIN HERE ========================================= @@ -434,4 +435,27 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and -limitations under the License. \ No newline at end of file +limitations under the License. + +NLipsum NOTICES AND INFORMATION BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2015 Alex Pendleton + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 16c34a1e0c..8ec519fae8 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -35,5 +35,6 @@ 1.26.0 11.2.1 6.13.1 + 1.1.0 \ No newline at end of file diff --git a/src/dev/impl/DevToys/Assets/Icons/LoremIpsum.svg b/src/dev/impl/DevToys/Assets/Icons/LoremIpsum.svg new file mode 100644 index 0000000000..8d07349b0f --- /dev/null +++ b/src/dev/impl/DevToys/Assets/Icons/LoremIpsum.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/src/dev/impl/DevToys/DevToys.csproj b/src/dev/impl/DevToys/DevToys.csproj index fa3b108e81..b7daa83b43 100644 --- a/src/dev/impl/DevToys/DevToys.csproj +++ b/src/dev/impl/DevToys/DevToys.csproj @@ -1,4 +1,4 @@ - + @@ -47,6 +47,8 @@ + + @@ -71,6 +73,9 @@ HtmlEncoderDecoderToolPage.xaml + + LoremIpsumGeneratorToolPage.xaml + PngJpgCompressorToolPage.xaml @@ -214,6 +219,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -496,6 +504,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + MSBuild:Compile Designer @@ -562,6 +574,7 @@ + diff --git a/src/dev/impl/DevToys/LanguageManager.cs b/src/dev/impl/DevToys/LanguageManager.cs index 50ac4a401f..5ee1765546 100644 --- a/src/dev/impl/DevToys/LanguageManager.cs +++ b/src/dev/impl/DevToys/LanguageManager.cs @@ -33,6 +33,7 @@ public partial class LanguageManager : ObservableObject private readonly JsonFormatterStrings _jsonformatter = new JsonFormatterStrings(); private readonly JsonYamlStrings _jsonyaml = new JsonYamlStrings(); private readonly JwtDecoderEncoderStrings _jwtdecoderencoder = new JwtDecoderEncoderStrings(); + private readonly LoremIpsumGeneratorStrings _loremipsumgenerator = new LoremIpsumGeneratorStrings(); private readonly MainPageStrings _mainpage = new MainPageStrings(); private readonly MarkdownPreviewStrings _markdownpreview = new MarkdownPreviewStrings(); private readonly NumberBaseConverterStrings _numberbaseconverter = new NumberBaseConverterStrings(); @@ -100,6 +101,11 @@ public partial class LanguageManager : ObservableObject /// public JwtDecoderEncoderStrings JwtDecoderEncoder => _jwtdecoderencoder; + /// + /// Gets the . + /// + public LoremIpsumGeneratorStrings LoremIpsumGenerator => _loremipsumgenerator; + /// /// Gets the . /// @@ -845,6 +851,76 @@ public class JwtDecoderEncoderStrings : ObservableObject public string SearchDisplayName => _resources.GetString("SearchDisplayName"); } + public class LoremIpsumGeneratorStrings : ObservableObject + { + private readonly ResourceLoader _resources = ResourceLoader.GetForViewIndependentUse("LoremIpsumGenerator"); + + /// + /// Gets the resource AccessibleName. + /// + public string AccessibleName => _resources.GetString("AccessibleName"); + + /// + /// Gets the resource Configuration. + /// + public string Configuration => _resources.GetString("Configuration"); + + /// + /// Gets the resource Description. + /// + public string Description => _resources.GetString("Description"); + + /// + /// Gets the resource LengthDescription. + /// + public string LengthDescription => _resources.GetString("LengthDescription"); + + /// + /// Gets the resource LengthTitle. + /// + public string LengthTitle => _resources.GetString("LengthTitle"); + + /// + /// Gets the resource MenuDisplayName. + /// + public string MenuDisplayName => _resources.GetString("MenuDisplayName"); + + /// + /// Gets the resource Output. + /// + public string Output => _resources.GetString("Output"); + + /// + /// Gets the resource ParagraphsType. + /// + public string ParagraphsType => _resources.GetString("ParagraphsType"); + + /// + /// Gets the resource SearchDisplayName. + /// + public string SearchDisplayName => _resources.GetString("SearchDisplayName"); + + /// + /// Gets the resource SentencesType. + /// + public string SentencesType => _resources.GetString("SentencesType"); + + /// + /// Gets the resource TypeDescription. + /// + public string TypeDescription => _resources.GetString("TypeDescription"); + + /// + /// Gets the resource TypeTitle. + /// + public string TypeTitle => _resources.GetString("TypeTitle"); + + /// + /// Gets the resource WordsType. + /// + public string WordsType => _resources.GetString("WordsType"); + } + public class MainPageStrings : ObservableObject { private readonly ResourceLoader _resources = ResourceLoader.GetForViewIndependentUse("MainPage"); diff --git a/src/dev/impl/DevToys/Strings/cs-CZ/LoremIpsumGenerator.resw b/src/dev/impl/DevToys/Strings/cs-CZ/LoremIpsumGenerator.resw new file mode 100644 index 0000000000..1644a5952c --- /dev/null +++ b/src/dev/impl/DevToys/Strings/cs-CZ/LoremIpsumGenerator.resw @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lorem Ipsum Generator tool + + + Configuration + + + Generate Lorem Ipsum placeholder text + + + Number of words, sentences or paragraphs to generate + + + Length + + + Lorem Ipsum + + + Output + + + Paragraphs + + + Lorem Ipsum Generator + + + Sentences + + + Generate words, sentences or paragraphs of Lorem Ipsum + + + Type + + + Words + + \ No newline at end of file diff --git a/src/dev/impl/DevToys/Strings/en-US/LoremIpsumGenerator.resw b/src/dev/impl/DevToys/Strings/en-US/LoremIpsumGenerator.resw new file mode 100644 index 0000000000..1644a5952c --- /dev/null +++ b/src/dev/impl/DevToys/Strings/en-US/LoremIpsumGenerator.resw @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lorem Ipsum Generator tool + + + Configuration + + + Generate Lorem Ipsum placeholder text + + + Number of words, sentences or paragraphs to generate + + + Length + + + Lorem Ipsum + + + Output + + + Paragraphs + + + Lorem Ipsum Generator + + + Sentences + + + Generate words, sentences or paragraphs of Lorem Ipsum + + + Type + + + Words + + \ No newline at end of file diff --git a/src/dev/impl/DevToys/Strings/fr-FR/LoremIpsumGenerator.resw b/src/dev/impl/DevToys/Strings/fr-FR/LoremIpsumGenerator.resw new file mode 100644 index 0000000000..1644a5952c --- /dev/null +++ b/src/dev/impl/DevToys/Strings/fr-FR/LoremIpsumGenerator.resw @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lorem Ipsum Generator tool + + + Configuration + + + Generate Lorem Ipsum placeholder text + + + Number of words, sentences or paragraphs to generate + + + Length + + + Lorem Ipsum + + + Output + + + Paragraphs + + + Lorem Ipsum Generator + + + Sentences + + + Generate words, sentences or paragraphs of Lorem Ipsum + + + Type + + + Words + + \ No newline at end of file diff --git a/src/dev/impl/DevToys/Strings/pl-PL/LoremIpsumGenerator.resw b/src/dev/impl/DevToys/Strings/pl-PL/LoremIpsumGenerator.resw new file mode 100644 index 0000000000..1644a5952c --- /dev/null +++ b/src/dev/impl/DevToys/Strings/pl-PL/LoremIpsumGenerator.resw @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lorem Ipsum Generator tool + + + Configuration + + + Generate Lorem Ipsum placeholder text + + + Number of words, sentences or paragraphs to generate + + + Length + + + Lorem Ipsum + + + Output + + + Paragraphs + + + Lorem Ipsum Generator + + + Sentences + + + Generate words, sentences or paragraphs of Lorem Ipsum + + + Type + + + Words + + \ No newline at end of file diff --git a/src/dev/impl/DevToys/Strings/ru-RU/LoremIpsumGenerator.resw b/src/dev/impl/DevToys/Strings/ru-RU/LoremIpsumGenerator.resw new file mode 100644 index 0000000000..1644a5952c --- /dev/null +++ b/src/dev/impl/DevToys/Strings/ru-RU/LoremIpsumGenerator.resw @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lorem Ipsum Generator tool + + + Configuration + + + Generate Lorem Ipsum placeholder text + + + Number of words, sentences or paragraphs to generate + + + Length + + + Lorem Ipsum + + + Output + + + Paragraphs + + + Lorem Ipsum Generator + + + Sentences + + + Generate words, sentences or paragraphs of Lorem Ipsum + + + Type + + + Words + + \ No newline at end of file diff --git a/src/dev/impl/DevToys/Strings/zh-CN/LoremIpsumGenerator.resw b/src/dev/impl/DevToys/Strings/zh-CN/LoremIpsumGenerator.resw new file mode 100644 index 0000000000..1644a5952c --- /dev/null +++ b/src/dev/impl/DevToys/Strings/zh-CN/LoremIpsumGenerator.resw @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lorem Ipsum Generator tool + + + Configuration + + + Generate Lorem Ipsum placeholder text + + + Number of words, sentences or paragraphs to generate + + + Length + + + Lorem Ipsum + + + Output + + + Paragraphs + + + Lorem Ipsum Generator + + + Sentences + + + Generate words, sentences or paragraphs of Lorem Ipsum + + + Type + + + Words + + \ No newline at end of file diff --git a/src/dev/impl/DevToys/ViewModels/Tools/Generators/LoremIpsumGenerator/LoremIpsumGeneratorToolProvider.cs b/src/dev/impl/DevToys/ViewModels/Tools/Generators/LoremIpsumGenerator/LoremIpsumGeneratorToolProvider.cs new file mode 100644 index 0000000000..076e077605 --- /dev/null +++ b/src/dev/impl/DevToys/ViewModels/Tools/Generators/LoremIpsumGenerator/LoremIpsumGeneratorToolProvider.cs @@ -0,0 +1,43 @@ +using System.Composition; +using Windows.UI.Xaml.Controls; +using DevToys.Api.Tools; +using DevToys.Core.Threading; +using DevToys.Shared.Api.Core; + +#nullable enable + +namespace DevToys.ViewModels.Tools.LoremIpsumGenerator +{ + [Export(typeof(IToolProvider))] + [Name("Lorem Ipsum Generator")] + [Parent(GeneratorsGroupToolProvider.InternalName)] + [ProtocolName("loremipsum")] + [Order(2)] + [CompactOverlaySize(width: 400, height: 500)] + internal sealed class LoremIpsumGeneratorToolProvider : ToolProviderBase, IToolProvider + { + private readonly IMefProvider _mefProvider; + + public string MenuDisplayName => LanguageManager.Instance.LoremIpsumGenerator.MenuDisplayName; + public string? SearchDisplayName => LanguageManager.Instance.LoremIpsumGenerator.SearchDisplayName; + public string? Description => LanguageManager.Instance.LoremIpsumGenerator.Description; + public string AccessibleName => LanguageManager.Instance.LoremIpsumGenerator.AccessibleName; + public TaskCompletionNotifier IconSource => CreateSvgIcon("LoremIpsum.svg"); + + [ImportingConstructor] + public LoremIpsumGeneratorToolProvider(IMefProvider mefProvider) + { + _mefProvider = mefProvider; + } + + public IToolViewModel CreateTool() + { + return _mefProvider.Import(); + } + + public bool CanBeTreatedByTool(string data) + { + return false; + } + } +} diff --git a/src/dev/impl/DevToys/ViewModels/Tools/Generators/LoremIpsumGenerator/LoremIpsumGeneratorToolViewModel.cs b/src/dev/impl/DevToys/ViewModels/Tools/Generators/LoremIpsumGenerator/LoremIpsumGeneratorToolViewModel.cs new file mode 100644 index 0000000000..9f126c4808 --- /dev/null +++ b/src/dev/impl/DevToys/ViewModels/Tools/Generators/LoremIpsumGenerator/LoremIpsumGeneratorToolViewModel.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Composition; +using System.Globalization; +using System.Security.AccessControl; +using System.Threading.Tasks; +using Windows.ApplicationModel.Background; +using DevToys.Api.Core; +using DevToys.Api.Core.Settings; +using DevToys.Api.Tools; +using DevToys.Core.Threading; +using DevToys.Shared.Core.Threading; +using DevToys.Views.Tools.LoremIpsumGenerator; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using NLipsum.Core; + +namespace DevToys.ViewModels.Tools.LoremIpsumGenerator +{ + [Export(typeof(LoremIpsumGeneratorToolViewModel))] + public sealed class LoremIpsumGeneratorToolViewModel : ObservableRecipient, IToolViewModel + { + private static readonly SettingDefinition Type + = new( + name: $"{nameof(LoremIpsumGeneratorToolViewModel)}.{nameof(Type)}", + isRoaming: true, + defaultValue: DefaultType); + + private static readonly SettingDefinition Length + = new( + name: $"{nameof(LoremIpsumGeneratorToolViewModel)}.{nameof(Length)}", + isRoaming: true, + defaultValue: 1); + + private const string ParagraphsType = "Paragraphs"; + private const string SentencesType = "Sentences"; + private const string WordsType = "Words"; + + private const string DefaultType = ParagraphsType; + + private readonly IMarketingService _marketingService; + private readonly ISettingsProvider _settingsProvider; + private readonly Queue<(string Type, int Length)> _generationQueue = new(); + + private string _output = string.Empty; + private bool _generationInProgress; + private bool _toolSuccessfullyWorked; + + public Type View => typeof(LoremIpsumGeneratorToolPage); + + internal LoremIpsumGeneratorStrings Strings => LanguageManager.Instance.LoremIpsumGenerator; + + internal string LoremIpsumType + { + get => _settingsProvider.GetSetting(Type); + set + { + if (_settingsProvider.GetSetting(Type) != value) + { + _settingsProvider.SetSetting(Type, value); + OnPropertyChanged(); + QueueGeneration(); + } + } + } + + internal int LoremIpsumLength + { + get => _settingsProvider.GetSetting(Length); + set + { + if (_settingsProvider.GetSetting(Length) != value) + { + _settingsProvider.SetSetting(Length, value); + OnPropertyChanged(); + QueueGeneration(); + } + } + } + + internal string Output + { + get => _output; + set => SetProperty(ref _output, value); + } + + [ImportingConstructor] + public LoremIpsumGeneratorToolViewModel(ISettingsProvider settingsProvider, IMarketingService marketingService) + { + _settingsProvider = settingsProvider; + _marketingService = marketingService; + + QueueGeneration(); + } + + private void QueueGeneration() + { + _generationQueue.Enqueue((LoremIpsumType, LoremIpsumLength)); + TreatQueueAsync().Forget(); + } + + private async Task TreatQueueAsync() + { + if (_generationInProgress) + { + return; + } + + _generationInProgress = true; + + await TaskScheduler.Default; + + while (_generationQueue.TryDequeue(out (string Type, int Length) options)) + { + string output = GenerateLipsum(options.Type, options.Length); + + ThreadHelper.RunOnUIThreadAsync(() => + { + Output = output; + + if (!_toolSuccessfullyWorked) + { + _toolSuccessfullyWorked = true; + _marketingService.NotifyToolSuccessfullyWorked(); + } + }).ForgetSafely(); + } + + _generationInProgress = false; + } + + private string GenerateLipsum(string type, int length) + { + if (length <= 0) + { + return string.Empty; + } + + var generator = new LipsumGenerator(); + + switch (type) + { + case WordsType: + string[] words = generator.GenerateWords(length); + words[0] = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(words[0]); + return string.Join(' ', words); + case SentencesType: + return string.Join(' ', generator.GenerateSentences(length, Sentence.Medium)); + case ParagraphsType: + return string.Join($"{Environment.NewLine}{Environment.NewLine}", + generator.GenerateParagraphs(length, Paragraph.Medium)); + default: + return string.Empty; + } + } + } +} diff --git a/src/dev/impl/DevToys/Views/Tools/LoremIpsumGenerator/LoremIpsumGeneratorToolPage.xaml b/src/dev/impl/DevToys/Views/Tools/LoremIpsumGenerator/LoremIpsumGeneratorToolPage.xaml new file mode 100644 index 0000000000..8abe609dd7 --- /dev/null +++ b/src/dev/impl/DevToys/Views/Tools/LoremIpsumGenerator/LoremIpsumGeneratorToolPage.xaml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/dev/impl/DevToys/Views/Tools/LoremIpsumGenerator/LoremIpsumGeneratorToolPage.xaml.cs b/src/dev/impl/DevToys/Views/Tools/LoremIpsumGenerator/LoremIpsumGeneratorToolPage.xaml.cs new file mode 100644 index 0000000000..3f3864a6d3 --- /dev/null +++ b/src/dev/impl/DevToys/Views/Tools/LoremIpsumGenerator/LoremIpsumGeneratorToolPage.xaml.cs @@ -0,0 +1,52 @@ +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Navigation; +using DevToys.Api.Core.Navigation; +using DevToys.Shared.Core; +using DevToys.ViewModels.Tools.LoremIpsumGenerator; + +namespace DevToys.Views.Tools.LoremIpsumGenerator +{ + public sealed partial class LoremIpsumGeneratorToolPage : Page + { + public static readonly DependencyProperty ViewModelProperty + = DependencyProperty.Register( + nameof(ViewModel), + typeof(LoremIpsumGeneratorToolViewModel), + typeof(LoremIpsumGeneratorToolPage), + new PropertyMetadata(null)); + + public LoremIpsumGeneratorToolViewModel ViewModel + { + get => (LoremIpsumGeneratorToolViewModel)GetValue(ViewModelProperty); + set => SetValue(ViewModelProperty, value); + } + + public LoremIpsumGeneratorToolPage() + { + InitializeComponent(); + } + + protected override void OnNavigatedTo(NavigationEventArgs e) + { + var parameters = (NavigationParameter)e.Parameter; + + if (ViewModel is null) + { + // Set the view model + Assumes.NotNull(parameters.ViewModel, nameof(parameters.ViewModel)); + ViewModel = (LoremIpsumGeneratorToolViewModel)parameters.ViewModel!; + DataContext = ViewModel; + } + + base.OnNavigatedTo(e); + } + } +}