From 0ebad363358701c92761be409db08965e546a255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Sat, 22 Feb 2020 22:31:19 +0100 Subject: [PATCH] enabled nullable --- ModernWpfPlayground.csproj | 5 ++ MvvmStuff/BaseViewModel.cs | 65 +++++------------------ MvvmStuff/RelayCommand.cs | 2 +- PropertyPresenter2/ValueConverter.cs | 2 +- WindowViewModel.cs | 79 ++++++++++++++++++++++++++-- 5 files changed, 96 insertions(+), 57 deletions(-) diff --git a/ModernWpfPlayground.csproj b/ModernWpfPlayground.csproj index ad58153..2ca7435 100644 --- a/ModernWpfPlayground.csproj +++ b/ModernWpfPlayground.csproj @@ -4,9 +4,14 @@ WinExe netcoreapp3.1 true + enable + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/MvvmStuff/BaseViewModel.cs b/MvvmStuff/BaseViewModel.cs index c6f21e6..c22fb9f 100644 --- a/MvvmStuff/BaseViewModel.cs +++ b/MvvmStuff/BaseViewModel.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; -using System.Reflection; using System.Runtime.CompilerServices; using System.Text.Json; using System.Windows; @@ -12,34 +11,34 @@ namespace ModernWpfPlayground.MvvmStuff { public abstract class BaseViewModel : INotifyPropertyChanged { - protected BaseViewModel() - { - _properties = GetType().GetProperties(); - } private readonly Dictionary _valueDict = new Dictionary(); - private readonly PropertyInfo[] _properties; - protected bool SetProperty(T value, [CallerMemberName] string propertyName = null) + protected bool SetProperty(T value, Action? onChanged = null, + [CallerMemberName] string? propertyName = null) { + if(propertyName == null) throw new ArgumentNullException(nameof(propertyName)); if (_valueDict.TryGetValue(propertyName, out var obj) && Equals(value, obj)) return false; - _valueDict[propertyName] = value; + _valueDict[propertyName] = value!; OnPropertyChanged(propertyName); + onChanged?.Invoke(value); return true; } - protected T GetProperty(T defaultValue = default, [CallerMemberName] string propertyName = null) + protected T GetProperty(T defaultValue = default, [CallerMemberName] string? propertyName = null) { + if (propertyName == null) throw new ArgumentNullException(nameof(propertyName)); return _valueDict.TryGetValue(propertyName, out var obj) ? (T) obj : defaultValue; } - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler? PropertyChanged; [NotifyPropertyChangedInvocator] [PublicAPI] - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { + if (propertyName == null) throw new ArgumentNullException(nameof(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } @@ -63,50 +62,14 @@ namespace ModernWpfPlayground.MvvmStuff } } - protected void LoadViewModel() + protected void MapDictionary(IEnumerable<(string, object?)> tuples) { - var openFileDialog = new OpenFileDialog {AddExtension = true, DefaultExt = "*.json"}; - var result = openFileDialog.ShowDialog(Application.Current.MainWindow?.Owner); - if (result != true) return; - var contents = File.ReadAllText(openFileDialog.FileName); - var obj = JsonSerializer.Deserialize>(contents); - foreach (var (key, value) in obj) + if (tuples == null) throw new ArgumentNullException(nameof(tuples)); + foreach (var (key, value) in tuples) { - _valueDict[key] = CastToType(key, value); + _valueDict[key] = value!; OnPropertyChanged(key); } } - - private object CastToType(string key, JsonElement value) - { - - var property = Array.Find(_properties, x => x.Name == key); - if (property.PropertyType == typeof(double)) - { - return value.GetDouble(); - } - - if (property.PropertyType == typeof(bool)) - { - return value.GetBoolean(); - } - - if (property.PropertyType == typeof(int)) - { - return value.GetInt32(); - } - - if (property.PropertyType.IsEnum) - { - return Enum.ToObject(property.PropertyType, value.GetInt32()); - } - - if (property.PropertyType == typeof(string)) - { - return value.GetString(); - } - - return default; - } } } \ No newline at end of file diff --git a/MvvmStuff/RelayCommand.cs b/MvvmStuff/RelayCommand.cs index fd3f92c..71d5cc4 100644 --- a/MvvmStuff/RelayCommand.cs +++ b/MvvmStuff/RelayCommand.cs @@ -5,7 +5,7 @@ namespace ModernWpfPlayground.MvvmStuff { public class RelayCommand : ICommand { - private readonly Predicate _canExecute; + private readonly Predicate? _canExecute; private readonly Action _execute; public RelayCommand(Action execute) diff --git a/PropertyPresenter2/ValueConverter.cs b/PropertyPresenter2/ValueConverter.cs index 3a5c6bc..ec8ec80 100644 --- a/PropertyPresenter2/ValueConverter.cs +++ b/PropertyPresenter2/ValueConverter.cs @@ -16,7 +16,7 @@ namespace ModernWpfPlayground.PropertyPresenter2 /// /// Makes an Bitmap from every Imageformat. /// - public class ObjectImageConverter : IValueConverter + public sealed class ObjectImageConverter : IValueConverter { object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) { diff --git a/WindowViewModel.cs b/WindowViewModel.cs index 1213f03..007e904 100644 --- a/WindowViewModel.cs +++ b/WindowViewModel.cs @@ -1,32 +1,47 @@ -using System.Threading.Tasks; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text.Json; +using System.Threading.Tasks; using System.Windows; using System.Windows.Input; +using Microsoft.Win32; using ModernWpfPlayground.MvvmStuff; namespace ModernWpfPlayground { public class WindowViewModel : BaseViewModel { + private readonly PropertyInfo[] _properties; + private string? _path; + public WindowViewModel() { - ShowDialogCommand = new RelayCommand(async x => await ShowDialogAsync()); + ShowDialogCommand = new RelayCommand(async x => await ShowDialogAsync().ConfigureAwait(false)); CloseCommand = new RelayCommand(x => Application.Current.Shutdown()); OpenViewModelCommand = new RelayCommand(x => LoadViewModel()); SaveViewModelCommand = new RelayCommand(x => SaveViewModel()); ResetViewModelCommand = new RelayCommand(x => ResetViewModel()); + _properties = GetType().GetProperties(); } private async Task ShowDialogAsync() { var dialog = new ContentDialogExample {Message = WelcomeMessage}; - var result = await dialog.ShowAsync(); + var result = await dialog.ShowAsync().ConfigureAwait(false); WelcomeMessage = result.ToString(); } public bool BooleanValue { get => GetProperty(true); - set => SetProperty(value); + set => SetProperty(value, BooleanValue_OnChanged); + } + + private void BooleanValue_OnChanged(bool obj) + { + VisibilityEnumTest = obj ? Visibility.Visible : Visibility.Collapsed; } public Visibility VisibilityEnumTest @@ -62,5 +77,61 @@ namespace ModernWpfPlayground public ICommand SaveViewModelCommand { get; } public ICommand ResetViewModelCommand { get; } + + private void LoadViewModel() + { + var list = ReadFromJson(); + MapDictionary(list); + } + + private IEnumerable<(string, object?)> ReadFromJson() + { + var openFileDialog = new OpenFileDialog { AddExtension = true, DefaultExt = "*.json" }; + var result = openFileDialog.ShowDialog(Application.Current.MainWindow?.Owner); + if (result != true) yield break; + + var contents = File.ReadAllText(_path = openFileDialog.FileName); + var obj = JsonSerializer.Deserialize>(contents); + foreach (var (key, value) in obj) + { + yield return (key, CastToType(key, value)); + } + } + + private object? CastToType(string key, JsonElement value) + { + + var property = Array.Find(_properties, x => x.Name == key); + if (property == null) + { + return default; + } + if (property.PropertyType == typeof(double)) + { + return value.GetDouble(); + } + + if (property.PropertyType == typeof(bool)) + { + return value.GetBoolean(); + } + + if (property.PropertyType == typeof(int)) + { + return value.GetInt32(); + } + + if (property.PropertyType.IsEnum) + { + return Enum.ToObject(property.PropertyType, value.GetInt32()); + } + + if (property.PropertyType == typeof(string)) + { + return value.GetString(); + } + + return default; + } } } \ No newline at end of file