diff --git a/src/Sms.TaskTwo.Avalonia/Views/MainWindow.axaml b/src/Sms.TaskTwo.Avalonia/Views/MainWindow.axaml
index 15cef0b..878eea8 100644
--- a/src/Sms.TaskTwo.Avalonia/Views/MainWindow.axaml
+++ b/src/Sms.TaskTwo.Avalonia/Views/MainWindow.axaml
@@ -57,7 +57,7 @@
Spacing="2">
+ IsVisible="{Binding HasAddVariableError}" />
_gridRows = new();
-
public MainWindow()
{
InitializeComponent();
@@ -24,71 +23,25 @@ public partial class MainWindow : Window
return;
}
- if (_gridRows.TryGetValue(row, out var previousRow) && previousRow != e.Row)
- {
- previousRow.DataContextChanged -= OnRowDataContextChanged;
- }
-
- _gridRows[row] = e.Row;
ApplyRowClasses(e.Row, row);
- row.RowAppearanceChanged -= OnRowAppearanceChanged;
- row.RowAppearanceChanged += OnRowAppearanceChanged;
-
- e.Row.DataContextChanged -= OnRowDataContextChanged;
- e.Row.DataContextChanged += OnRowDataContextChanged;
- }
-
- private void OnRowDataContextChanged(object? sender, EventArgs e)
- {
- if (sender is not DataGridRow gridRow)
+ PropertyChangedEventHandler? handler = null;
+ handler = (_, args) =>
{
- return;
- }
+ if (args.PropertyName is nameof(EnvironmentVariableRowViewModel.UseUserStore))
+ {
+ ApplyRowClasses(e.Row, row);
+ }
+ };
- var row = _gridRows.FirstOrDefault(pair => pair.Value == gridRow).Key;
- if (row is null)
- {
- return;
- }
-
- row.RowAppearanceChanged -= OnRowAppearanceChanged;
- _gridRows.Remove(row);
- gridRow.DataContextChanged -= OnRowDataContextChanged;
- }
-
- private void OnRowAppearanceChanged(object? sender, EventArgs e)
- {
- if (sender is not EnvironmentVariableRowViewModel row)
- {
- return;
- }
-
- if (_gridRows.TryGetValue(row, out var gridRow))
- {
- ApplyRowClasses(gridRow, row);
- }
+ row.PropertyChanged += handler;
+ e.Row.DetachedFromVisualTree += (_, _) => row.PropertyChanged -= handler;
}
private static void ApplyRowClasses(DataGridRow gridRow, EnvironmentVariableRowViewModel row)
{
- gridRow.Classes.Remove("appSettings");
- gridRow.Classes.Remove("custom");
- gridRow.Classes.Remove("userStore");
-
- if (row.IsFromAppSettings)
- {
- gridRow.Classes.Add("appSettings");
- }
-
- if (row.IsCustom)
- {
- gridRow.Classes.Add("custom");
- }
-
- if (row.UseUserStore)
- {
- gridRow.Classes.Add("userStore");
- }
+ gridRow.Classes.Set("appSettings", row.IsFromAppSettings);
+ gridRow.Classes.Set("custom", row.IsCustom);
+ gridRow.Classes.Set("userStore", row.UseUserStore);
}
}
diff --git a/src/Sms.TaskTwo.Core/Services/EnvironmentVariablesService.cs b/src/Sms.TaskTwo.Core/Services/EnvironmentVariablesService.cs
index 688a9e3..57040d7 100644
--- a/src/Sms.TaskTwo.Core/Services/EnvironmentVariablesService.cs
+++ b/src/Sms.TaskTwo.Core/Services/EnvironmentVariablesService.cs
@@ -36,12 +36,11 @@ public sealed class EnvironmentVariablesService
_options = options.Value;
_log = log;
_configuredNames = new HashSet(_options.Names, StringComparer.Ordinal);
+ ReloadMetadata();
}
public void EnsureConfiguredVariablesExist()
{
- ReloadMetadata();
-
foreach (var name in _options.Names)
{
if (_store.IsPersistedInUserStore(name))
@@ -51,8 +50,7 @@ public sealed class EnvironmentVariablesService
var value = ResolveRequiredValue(name);
_store.Set(name, value);
- _log.WriteLine(
- $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [INFO] Created configured variable: {name}={value}");
+ LogInfo($"Created configured variable: {name}={value}");
}
}
@@ -97,7 +95,6 @@ public sealed class EnvironmentVariablesService
public bool TryAddCustomVariable(string name, string value, out string? errorMessage)
{
- ReloadMetadata();
name = name.Trim();
if (string.IsNullOrWhiteSpace(name))
@@ -127,20 +124,16 @@ public sealed class EnvironmentVariablesService
_customNames.Add(name);
PersistCustomNames();
_store.Set(name, value);
- _log.WriteLine(
- $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [INFO] Created custom variable: {name}={value}");
+ LogInfo($"Created custom variable: {name}={value}");
errorMessage = null;
return true;
}
- public EnvironmentVariableRow GetRowSnapshot(string name)
- {
- ReloadMetadata();
- return CreateRow(name, ResolveRequiredValue(name));
- }
+ public EnvironmentVariableRow GetRowSnapshot(string name) =>
+ CreateRow(name, ResolveRequiredValue(name));
- public string GetDisplayValue(string name) => ResolveRequiredValue(name);
+ public string GetRequiredValue(string name) => ResolveRequiredValue(name);
public string? GetProcessValue(string name) =>
_store.GetProcessEnvironment().TryGetValue(name, out var value) ? value : null;
@@ -149,8 +142,7 @@ public sealed class EnvironmentVariablesService
{
var previous = _store.GetUserPersistedValue(name);
_store.Set(name, value);
- _log.WriteLine(
- $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [INFO] Changed value: {name}={value} (previous: {previous ?? ""})");
+ LogInfo($"Changed value: {name}={value} (previous: {previous ?? ""})");
}
public void SaveComment(string name, string comment)
@@ -158,22 +150,18 @@ public sealed class EnvironmentVariablesService
var previous = _comments.GetValueOrDefault(name, string.Empty);
_comments[name] = comment;
PersistComments();
- _log.WriteLine(
- $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [INFO] Changed comment: {name}={comment} (previous: {(string.IsNullOrEmpty(previous) ? "" : previous)})");
+ LogInfo($"Changed comment: {name}={comment} (previous: {(string.IsNullOrEmpty(previous) ? "" : previous)})");
}
public void RemoveVariable(string name)
{
- ReloadMetadata();
-
if (IsCustom(name))
{
_customNames.Remove(name);
PersistCustomNames();
_comments.Remove(name);
PersistComments();
- _log.WriteLine(
- $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [INFO] Removed custom variable from list: {name}");
+ LogInfo($"Removed custom variable from list: {name}");
}
DeleteFromUserStore(name);
@@ -188,8 +176,7 @@ public sealed class EnvironmentVariablesService
var previous = _store.GetUserPersistedValue(name);
_store.RemoveFromUserStore(name);
- _log.WriteLine(
- $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [INFO] Removed from user store: {name} (previous: {previous ?? ""})");
+ LogInfo($"Removed from user store: {name} (previous: {previous ?? ""})");
}
public bool IsCustom(string name) => _customNames.Contains(name, StringComparer.Ordinal);
@@ -227,12 +214,7 @@ public sealed class EnvironmentVariablesService
if (_configuredNames.Contains(name) || _customNames.Contains(name))
{
- if (_options.Defaults.TryGetValue(name, out var defaultValue))
- {
- return defaultValue;
- }
-
- return string.Empty;
+ return _options.Defaults.TryGetValue(name, out var defaultValue) ? defaultValue : string.Empty;
}
return string.Empty;
@@ -252,8 +234,7 @@ public sealed class EnvironmentVariablesService
}
catch (JsonException ex)
{
- _log.WriteLine(
- $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [WARN] Failed to parse custom variables {_options.CustomVariablesVariableName}: {ex.Message}");
+ LogWarn($"Failed to parse custom variables {_options.CustomVariablesVariableName}: {ex.Message}");
return [];
}
}
@@ -279,8 +260,7 @@ public sealed class EnvironmentVariablesService
}
catch (JsonException ex)
{
- _log.WriteLine(
- $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [WARN] Failed to parse comments variable {_options.CommentsVariableName}: {ex.Message}");
+ LogWarn($"Failed to parse comments variable {_options.CommentsVariableName}: {ex.Message}");
return new Dictionary(StringComparer.Ordinal);
}
}
@@ -290,4 +270,10 @@ public sealed class EnvironmentVariablesService
var json = JsonSerializer.Serialize(_comments, JsonOptions);
_store.Set(_options.CommentsVariableName, json);
}
+
+ private void LogInfo(string message) =>
+ _log.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [INFO] {message}");
+
+ private void LogWarn(string message) =>
+ _log.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [WARN] {message}");
}
diff --git a/src/Sms.TaskTwo.ViewModels/EnvironmentVariableRowViewModel.cs b/src/Sms.TaskTwo.ViewModels/EnvironmentVariableRowViewModel.cs
index ed3f66b..0545d59 100644
--- a/src/Sms.TaskTwo.ViewModels/EnvironmentVariableRowViewModel.cs
+++ b/src/Sms.TaskTwo.ViewModels/EnvironmentVariableRowViewModel.cs
@@ -36,6 +36,7 @@ public sealed partial class EnvironmentVariableRowViewModel : ObservableObject
private bool _useUserStore;
[ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(ActualValueDisplay))]
private string _actualValue = string.Empty;
public string ActualValueDisplay =>
@@ -49,8 +50,6 @@ public sealed partial class EnvironmentVariableRowViewModel : ObservableObject
partial void OnUseUserStoreChanged(bool value)
{
- RowAppearanceChanged?.Invoke(this, EventArgs.Empty);
-
if (_isLoading)
{
return;
@@ -58,9 +57,7 @@ public sealed partial class EnvironmentVariableRowViewModel : ObservableObject
if (IsFromAppSettings && !value)
{
- BeginLoad();
- UseUserStore = true;
- EndLoad();
+ RunWithoutSave(() => UseUserStore = true);
return;
}
@@ -79,14 +76,10 @@ public sealed partial class EnvironmentVariableRowViewModel : ObservableObject
}
_service.DeleteFromUserStore(Field);
- BeginLoad();
- RequiredValue = _service.GetDisplayValue(Field);
- EndLoad();
+ RunWithoutSave(() => RequiredValue = _service.GetRequiredValue(Field));
RefreshActualValue(_service.GetProcessValue(Field));
}
- partial void OnActualValueChanged(string value) => OnPropertyChanged(nameof(ActualValueDisplay));
-
partial void OnRequiredValueChanged(string value)
{
if (_isLoading || !UseUserStore)
@@ -98,22 +91,22 @@ public sealed partial class EnvironmentVariableRowViewModel : ObservableObject
RefreshActualValue(_service.GetProcessValue(Field));
}
- public event EventHandler? RowAppearanceChanged;
-
public void ApplySnapshot(EnvironmentVariableRow row, bool suppressSave = false)
{
if (suppressSave)
{
- BeginLoad();
+ RunWithoutSave(ApplyValues);
+ }
+ else
+ {
+ ApplyValues();
}
- RequiredValue = row.Value;
- Comment = row.Comment;
- UseUserStore = row.IsFromAppSettings || row.IsPersistedInUserStore;
-
- if (suppressSave)
+ void ApplyValues()
{
- EndLoad();
+ RequiredValue = row.Value;
+ Comment = row.Comment;
+ UseUserStore = row.IsFromAppSettings || row.IsPersistedInUserStore;
}
}
@@ -122,10 +115,6 @@ public sealed partial class EnvironmentVariableRowViewModel : ObservableObject
ActualValue = processValue ?? string.Empty;
}
- public void BeginLoad() => _isLoading = true;
-
- public void EndLoad() => _isLoading = false;
-
partial void OnCommentChanged(string value)
{
if (_isLoading)
@@ -135,4 +124,17 @@ public sealed partial class EnvironmentVariableRowViewModel : ObservableObject
_service.SaveComment(Field, value);
}
+
+ private void RunWithoutSave(Action action)
+ {
+ _isLoading = true;
+ try
+ {
+ action();
+ }
+ finally
+ {
+ _isLoading = false;
+ }
+ }
}
diff --git a/src/Sms.TaskTwo.ViewModels/MainWindowViewModel.cs b/src/Sms.TaskTwo.ViewModels/MainWindowViewModel.cs
index a1ce390..67d59ab 100644
--- a/src/Sms.TaskTwo.ViewModels/MainWindowViewModel.cs
+++ b/src/Sms.TaskTwo.ViewModels/MainWindowViewModel.cs
@@ -30,8 +30,11 @@ public sealed partial class MainWindowViewModel : ObservableObject
private string _newVariableValue = string.Empty;
[ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(HasAddVariableError))]
private string? _addVariableError;
+ public bool HasAddVariableError => !string.IsNullOrEmpty(AddVariableError);
+
partial void OnShowAllVariablesChanged(bool value) => SyncRowsFromService();
partial void OnNewVariableNameChanged(string value) => AddVariableCommand.NotifyCanExecuteChanged();
@@ -59,18 +62,18 @@ public sealed partial class MainWindowViewModel : ObservableObject
private EnvironmentVariableRowViewModel CreateRowViewModel(EnvironmentVariableRow row)
{
- EnvironmentVariableRowViewModel? viewModel = null;
- viewModel = new EnvironmentVariableRowViewModel(
+ var field = row.Field;
+ return new EnvironmentVariableRowViewModel(
row,
_service,
onCustomRemoved: () =>
{
- if (viewModel is not null)
+ var existing = Rows.FirstOrDefault(r => r.Field == field);
+ if (existing is not null)
{
- Rows.Remove(viewModel);
+ Rows.Remove(existing);
}
});
- return viewModel;
}
private int FindInsertIndexForCustomVariable()
@@ -128,11 +131,6 @@ public sealed partial class MainWindowViewModel : ObservableObject
}
}
- RefreshProcessStates();
- }
-
- private void RefreshProcessStates()
- {
foreach (var row in Rows)
{
row.RefreshActualValue(_service.GetProcessValue(row.Field));
diff --git a/src/Sms.TaskTwo.Wpf/App.xaml b/src/Sms.TaskTwo.Wpf/App.xaml
index d523f36..243195b 100644
--- a/src/Sms.TaskTwo.Wpf/App.xaml
+++ b/src/Sms.TaskTwo.Wpf/App.xaml
@@ -4,6 +4,7 @@
Startup="OnStartup"
Exit="OnExit">
+
+
+
+
+
-
-
+
-
-
-
-
-
+
-
-
-
+
+ RowStyle="{StaticResource VariableRowStyle}"
+ ItemsSource="{Binding Rows}">
diff --git a/src/Sms.TaskTwo.Wpf/Views/MainWindow.xaml.cs b/src/Sms.TaskTwo.Wpf/Views/MainWindow.xaml.cs
index acaa3ab..5d76199 100644
--- a/src/Sms.TaskTwo.Wpf/Views/MainWindow.xaml.cs
+++ b/src/Sms.TaskTwo.Wpf/Views/MainWindow.xaml.cs
@@ -1,128 +1,13 @@
using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
using Sms.TaskTwo.ViewModels;
namespace Sms.TaskTwo.Wpf.Views;
public partial class MainWindow : Window
{
- private static readonly Brush AppSettingsBrush = new SolidColorBrush(Color.FromRgb(0xE3, 0xF2, 0xFD));
- private static readonly Brush CustomBrush = new SolidColorBrush(Color.FromRgb(0xFF, 0xF8, 0xE1));
- private static readonly Brush AppSettingsUserStoreBrush = new SolidColorBrush(Color.FromRgb(0xC8, 0xE6, 0xC9));
- private static readonly Brush UserStoreBorderBrush = new SolidColorBrush(Color.FromRgb(0x2E, 0x7D, 0x32));
- private static readonly Brush DefaultRowBrush = Brushes.White;
-
- private readonly Dictionary _gridRows = new();
-
- public MainWindow()
+ public MainWindow(MainWindowViewModel viewModel)
{
InitializeComponent();
- }
-
- public MainWindow(MainWindowViewModel viewModel) : this()
- {
DataContext = viewModel;
}
-
- private void OnLoadingRow(object sender, DataGridRowEventArgs e)
- {
- if (e.Row.DataContext is not EnvironmentVariableRowViewModel row)
- {
- return;
- }
-
- if (_gridRows.TryGetValue(row, out var previousRow) && previousRow != e.Row)
- {
- UnsubscribeRow(previousRow, row);
- }
-
- _gridRows[row] = e.Row;
- ApplyRowStyle(e.Row, row);
-
- row.RowAppearanceChanged -= OnRowAppearanceChanged;
- row.RowAppearanceChanged += OnRowAppearanceChanged;
-
- e.Row.DataContextChanged -= OnRowDataContextChanged;
- e.Row.DataContextChanged += OnRowDataContextChanged;
- }
-
- private void OnUnloadingRow(object sender, DataGridRowEventArgs e)
- {
- var row = _gridRows.FirstOrDefault(pair => pair.Value == e.Row).Key;
- if (row is null)
- {
- return;
- }
-
- UnsubscribeRow(e.Row, row);
- _gridRows.Remove(row);
- }
-
- private void UnsubscribeRow(DataGridRow gridRow, EnvironmentVariableRowViewModel row)
- {
- row.RowAppearanceChanged -= OnRowAppearanceChanged;
- gridRow.DataContextChanged -= OnRowDataContextChanged;
- }
-
- private void OnRowDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
- {
- if (sender is not DataGridRow gridRow)
- {
- return;
- }
-
- var row = _gridRows.FirstOrDefault(pair => pair.Value == gridRow).Key;
- if (row is null)
- {
- return;
- }
-
- UnsubscribeRow(gridRow, row);
- _gridRows.Remove(row);
- }
-
- private void OnRowAppearanceChanged(object? sender, EventArgs e)
- {
- if (sender is not EnvironmentVariableRowViewModel row)
- {
- return;
- }
-
- if (_gridRows.TryGetValue(row, out var gridRow))
- {
- ApplyRowStyle(gridRow, row);
- }
- }
-
- private static void ApplyRowStyle(DataGridRow gridRow, EnvironmentVariableRowViewModel row)
- {
- if (row.IsFromAppSettings && row.UseUserStore)
- {
- gridRow.Background = AppSettingsUserStoreBrush;
- }
- else if (row.IsFromAppSettings)
- {
- gridRow.Background = AppSettingsBrush;
- }
- else if (row.IsCustom)
- {
- gridRow.Background = CustomBrush;
- }
- else
- {
- gridRow.Background = DefaultRowBrush;
- }
-
- if (row.UseUserStore)
- {
- gridRow.BorderBrush = UserStoreBorderBrush;
- gridRow.BorderThickness = new Thickness(0, 0, 0, 2);
- }
- else
- {
- gridRow.BorderBrush = Brushes.Transparent;
- gridRow.BorderThickness = new Thickness(0);
- }
- }
}