From 7496ef80a10a15647b503846ff9ce1d47206ca01 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 12:27:59 +0000 Subject: [PATCH 1/6] Initial plan From b81eea7edaf318f75152c8b65116ec255a3a264c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 12:35:53 +0000 Subject: [PATCH 2/6] Add SetProperty helper and DialogViewModelBase to reduce code duplication Co-authored-by: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com> --- .../PropertyChangedBase.cs | 21 +++++++- .../ViewModels/DialogViewModelBase.cs | 33 ++++++++++++ .../ViewModels/DropdownViewModel.cs | 39 ++------------ .../HostsFileEditorEntryViewModel.cs | 54 +++---------------- .../IPAddressAndSubnetmaskViewModel.cs | 29 ++-------- .../ViewModels/IPAddressViewModel.cs | 20 ++----- .../OKCancelInfoMessageViewModel.cs | 15 ++---- 7 files changed, 75 insertions(+), 136 deletions(-) create mode 100644 Source/NETworkManager/ViewModels/DialogViewModelBase.cs diff --git a/Source/NETworkManager.Utilities/PropertyChangedBase.cs b/Source/NETworkManager.Utilities/PropertyChangedBase.cs index 5a16bf302f..8e049d651b 100644 --- a/Source/NETworkManager.Utilities/PropertyChangedBase.cs +++ b/Source/NETworkManager.Utilities/PropertyChangedBase.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System.Collections.Generic; +using System.ComponentModel; using System.Runtime.CompilerServices; namespace NETworkManager.Utilities; @@ -11,4 +12,22 @@ protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } + + /// + /// Sets the property value and raises PropertyChanged event if the value has changed. + /// + /// The type of the property. + /// Reference to the backing field. + /// The new value to set. + /// Name of the property (automatically captured). + /// True if the value changed and PropertyChanged was raised; otherwise false. + protected bool SetProperty(ref T field, T value, [CallerMemberName] string propertyName = null) + { + if (EqualityComparer.Default.Equals(field, value)) + return false; + + field = value; + OnPropertyChanged(propertyName); + return true; + } } \ No newline at end of file diff --git a/Source/NETworkManager/ViewModels/DialogViewModelBase.cs b/Source/NETworkManager/ViewModels/DialogViewModelBase.cs new file mode 100644 index 0000000000..7384a65920 --- /dev/null +++ b/Source/NETworkManager/ViewModels/DialogViewModelBase.cs @@ -0,0 +1,33 @@ +using System; +using System.Windows.Input; +using NETworkManager.Utilities; + +namespace NETworkManager.ViewModels; + +/// +/// Base class for dialog ViewModels that have OK and Cancel commands. +/// +/// The type of the derived ViewModel. +public abstract class DialogViewModelBase : ViewModelBase where T : DialogViewModelBase +{ + /// + /// Command executed when OK button is clicked. + /// + public ICommand OKCommand { get; } + + /// + /// Command executed when Cancel button is clicked. + /// + public ICommand CancelCommand { get; } + + /// + /// Initializes a new instance of the class. + /// + /// Action to execute when OK is clicked. + /// Action to execute when Cancel is clicked. + protected DialogViewModelBase(Action okCommand, Action cancelHandler) + { + OKCommand = new RelayCommand(_ => okCommand((T)this)); + CancelCommand = new RelayCommand(_ => cancelHandler((T)this)); + } +} diff --git a/Source/NETworkManager/ViewModels/DropdownViewModel.cs b/Source/NETworkManager/ViewModels/DropdownViewModel.cs index 38215d4a1b..864227d0a4 100644 --- a/Source/NETworkManager/ViewModels/DropdownViewModel.cs +++ b/Source/NETworkManager/ViewModels/DropdownViewModel.cs @@ -1,12 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Windows.Input; -using NETworkManager.Utilities; namespace NETworkManager.ViewModels; -public class DropdownViewModel : ViewModelBase +public class DropdownViewModel : DialogViewModelBase { private readonly string _valueDescription; @@ -16,56 +14,29 @@ public class DropdownViewModel : ViewModelBase public DropdownViewModel(Action okCommand, Action cancelHandler, List values, string valueDescription) + : base(okCommand, cancelHandler) { ValueDescription = valueDescription; Values = values; SelectedValue = Values.FirstOrDefault(); - - OKCommand = new RelayCommand(_ => okCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); } - public ICommand OKCommand { get; } - - public ICommand CancelCommand { get; } - public string ValueDescription { get => _valueDescription; - private init - { - if (value == _valueDescription) - return; - - _valueDescription = value; - OnPropertyChanged(); - } + private init => SetProperty(ref _valueDescription, value); } public List Values { get => _values; - private init - { - if (value == _values) - return; - - _values = value; - OnPropertyChanged(); - } + private init => SetProperty(ref _values, value); } public string SelectedValue { get => _selectedValue; - set - { - if (value == _selectedValue) - return; - - _selectedValue = value; - OnPropertyChanged(); - } + set => SetProperty(ref _selectedValue, value); } } \ No newline at end of file diff --git a/Source/NETworkManager/ViewModels/HostsFileEditorEntryViewModel.cs b/Source/NETworkManager/ViewModels/HostsFileEditorEntryViewModel.cs index 52ac61b05f..d3f382a610 100644 --- a/Source/NETworkManager/ViewModels/HostsFileEditorEntryViewModel.cs +++ b/Source/NETworkManager/ViewModels/HostsFileEditorEntryViewModel.cs @@ -1,14 +1,12 @@ using NETworkManager.Models.HostsFileEditor; -using NETworkManager.Utilities; using System; -using System.Windows.Input; namespace NETworkManager.ViewModels; /// /// ViewModel for adding or editing a hosts file entry in the HostsFileEditor dialog. /// -public class HostsFileEditorEntryViewModel : ViewModelBase +public class HostsFileEditorEntryViewModel : DialogViewModelBase { /// /// Creates a new instance of for adding or @@ -19,10 +17,8 @@ public class HostsFileEditorEntryViewModel : ViewModelBase /// Entry to edit, if null a new entry will be created. public HostsFileEditorEntryViewModel(Action okCommand, Action cancelHandler, HostsFileEntry entry = null) + : base(okCommand, cancelHandler) { - OKCommand = new RelayCommand(_ => okCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); - Entry = entry; // Add entry @@ -40,16 +36,6 @@ public HostsFileEditorEntryViewModel(Action okCom } } - /// - /// OK command to save the entry. - /// - public ICommand OKCommand { get; } - - /// - /// Cancel command to discard the entry. - /// - public ICommand CancelCommand { get; } - public HostsFileEntry Entry { get; } = null; /// @@ -63,14 +49,7 @@ public HostsFileEditorEntryViewModel(Action okCom public bool IsEnabled { get => _isEnabled; - set - { - if (value == _isEnabled) - return; - - _isEnabled = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isEnabled, value); } /// @@ -84,14 +63,7 @@ public bool IsEnabled public string IPAddress { get => _ipAddress; - set - { - if (value == _ipAddress) - return; - - _ipAddress = value; - OnPropertyChanged(); - } + set => SetProperty(ref _ipAddress, value); } /// @@ -106,14 +78,7 @@ public string IPAddress public string Hostname { get => _hostname; - set - { - if (value == _hostname) - return; - - _hostname = value; - OnPropertyChanged(); - } + set => SetProperty(ref _hostname, value); } /// @@ -127,13 +92,6 @@ public string Hostname public string Comment { get => _comment; - set - { - if (value == _comment) - return; - - _comment = value; - OnPropertyChanged(); - } + set => SetProperty(ref _comment, value); } } \ No newline at end of file diff --git a/Source/NETworkManager/ViewModels/IPAddressAndSubnetmaskViewModel.cs b/Source/NETworkManager/ViewModels/IPAddressAndSubnetmaskViewModel.cs index 8f728e8d61..30e3e74830 100644 --- a/Source/NETworkManager/ViewModels/IPAddressAndSubnetmaskViewModel.cs +++ b/Source/NETworkManager/ViewModels/IPAddressAndSubnetmaskViewModel.cs @@ -1,10 +1,8 @@ using System; -using System.Windows.Input; -using NETworkManager.Utilities; namespace NETworkManager.ViewModels; -public class IPAddressAndSubnetmaskViewModel : ViewModelBase +public class IPAddressAndSubnetmaskViewModel : DialogViewModelBase { private string _ipAddress; @@ -12,38 +10,19 @@ public class IPAddressAndSubnetmaskViewModel : ViewModelBase public IPAddressAndSubnetmaskViewModel(Action okCommand, Action cancelHandler) + : base(okCommand, cancelHandler) { - OKCommand = new RelayCommand(_ => okCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); } - public ICommand OKCommand { get; } - - public ICommand CancelCommand { get; } - public string IPAddress { get => _ipAddress; - set - { - if (value == _ipAddress) - return; - - _ipAddress = value; - OnPropertyChanged(); - } + set => SetProperty(ref _ipAddress, value); } public string Subnetmask { get => _subnetmask; - set - { - if (value == _subnetmask) - return; - - _subnetmask = value; - OnPropertyChanged(); - } + set => SetProperty(ref _subnetmask, value); } } \ No newline at end of file diff --git a/Source/NETworkManager/ViewModels/IPAddressViewModel.cs b/Source/NETworkManager/ViewModels/IPAddressViewModel.cs index 22e7bd4b69..f1fed09ca2 100644 --- a/Source/NETworkManager/ViewModels/IPAddressViewModel.cs +++ b/Source/NETworkManager/ViewModels/IPAddressViewModel.cs @@ -1,33 +1,19 @@ using System; -using System.Windows.Input; -using NETworkManager.Utilities; namespace NETworkManager.ViewModels; -public abstract class IPAddressViewModel : ViewModelBase +public abstract class IPAddressViewModel : DialogViewModelBase { private string _ipAddress; protected IPAddressViewModel(Action okCommand, Action cancelHandler) + : base(okCommand, cancelHandler) { - OKCommand = new RelayCommand(_ => okCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); } - public ICommand OKCommand { get; } - - public ICommand CancelCommand { get; } - public string IPAddress { get => _ipAddress; - set - { - if (value == _ipAddress) - return; - - _ipAddress = value; - OnPropertyChanged(); - } + set => SetProperty(ref _ipAddress, value); } } \ No newline at end of file diff --git a/Source/NETworkManager/ViewModels/OKCancelInfoMessageViewModel.cs b/Source/NETworkManager/ViewModels/OKCancelInfoMessageViewModel.cs index 69f4f83266..b225d97d88 100644 --- a/Source/NETworkManager/ViewModels/OKCancelInfoMessageViewModel.cs +++ b/Source/NETworkManager/ViewModels/OKCancelInfoMessageViewModel.cs @@ -1,27 +1,20 @@ -using NETworkManager.Utilities; -using System; -using System.Windows.Input; +using System; namespace NETworkManager.ViewModels; -public class OKCancelInfoMessageViewModel : ViewModelBase +public class OKCancelInfoMessageViewModel : DialogViewModelBase { public OKCancelInfoMessageViewModel(Action okCommand, Action cancelHandler, string message, string okButtonText = null, string cancelButtonText = null, ChildWindowIcon icon = ChildWindowIcon.Info) + : base(okCommand, cancelHandler) { - OKCommand = new RelayCommand(_ => okCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); - Message = message; OKButtonText = okButtonText ?? Localization.Resources.Strings.OK; CancelButtonText = cancelButtonText ?? Localization.Resources.Strings.Cancel; + Icon = icon; } - public ICommand OKCommand { get; } - - public ICommand CancelCommand { get; } - private readonly string _message; public string Message { From 1d4c7664712fc32dedeb7b79d42ba644a7827420 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 12:38:56 +0000 Subject: [PATCH 3/6] Refactor more ViewModels to use DialogViewModelBase and SetProperty Co-authored-by: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com> --- .../CredentialsChangePasswordViewModel.cs | 34 ++------------ ...CredentialsPasswordProfileFileViewModel.cs | 47 +++---------------- .../CredentialsPasswordViewModel.cs | 26 ++-------- .../CredentialsSetPasswordViewModel.cs | 34 ++------------ 4 files changed, 17 insertions(+), 124 deletions(-) diff --git a/Source/NETworkManager/ViewModels/CredentialsChangePasswordViewModel.cs b/Source/NETworkManager/ViewModels/CredentialsChangePasswordViewModel.cs index 9a29dc2507..4d88792acf 100644 --- a/Source/NETworkManager/ViewModels/CredentialsChangePasswordViewModel.cs +++ b/Source/NETworkManager/ViewModels/CredentialsChangePasswordViewModel.cs @@ -1,11 +1,10 @@ using System; using System.Security; -using System.Windows.Input; using NETworkManager.Utilities; namespace NETworkManager.ViewModels; -public class CredentialsChangePasswordViewModel : ViewModelBase +public class CredentialsChangePasswordViewModel : DialogViewModelBase { /// /// Private variable for . @@ -40,21 +39,10 @@ public class CredentialsChangePasswordViewModel : ViewModelBase /// which is executed on cancel click. public CredentialsChangePasswordViewModel(Action okCommand, Action cancelHandler) + : base(okCommand, cancelHandler) { - OKCommand = new RelayCommand(_ => okCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); } - /// - /// Command which is called when the OK button is clicked. - /// - public ICommand OKCommand { get; } - - /// - /// Command which is called when the cancel button is clicked. - /// - public ICommand CancelCommand { get; } - /// /// Password as . /// @@ -118,14 +106,7 @@ public SecureString NewPasswordRepeat public bool IsPasswordEmpty { get => _isPasswordEmpty; - set - { - if (value == _isPasswordEmpty) - return; - - _isPasswordEmpty = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isPasswordEmpty, value); } /// @@ -134,14 +115,7 @@ public bool IsPasswordEmpty public bool IsRepeatedPasswordEqual { get => _isRepeatedPasswordEqual; - set - { - if (value == _isRepeatedPasswordEqual) - return; - - _isRepeatedPasswordEqual = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isRepeatedPasswordEqual, value); } /// diff --git a/Source/NETworkManager/ViewModels/CredentialsPasswordProfileFileViewModel.cs b/Source/NETworkManager/ViewModels/CredentialsPasswordProfileFileViewModel.cs index 6ad8a41c67..826bec3411 100644 --- a/Source/NETworkManager/ViewModels/CredentialsPasswordProfileFileViewModel.cs +++ b/Source/NETworkManager/ViewModels/CredentialsPasswordProfileFileViewModel.cs @@ -1,11 +1,9 @@ -using NETworkManager.Utilities; -using System; +using System; using System.Security; -using System.Windows.Input; namespace NETworkManager.ViewModels; -public class CredentialsPasswordProfileFileViewModel : ViewModelBase +public class CredentialsPasswordProfileFileViewModel : DialogViewModelBase { /// /// Private variable for . @@ -38,38 +36,19 @@ public class CredentialsPasswordProfileFileViewModel : ViewModelBase public CredentialsPasswordProfileFileViewModel(Action okCommand, Action cancelHandler, string profileName, bool showWrongPassword = false) + : base(okCommand, cancelHandler) { - OKCommand = new RelayCommand(_ => okCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); - ProfileName = profileName; ShowWrongPassword = showWrongPassword; } - /// - /// Command which is called when the OK button is clicked. - /// - public ICommand OKCommand { get; } - - /// - /// Command which is called when the cancel button is clicked. - /// - public ICommand CancelCommand { get; } - /// /// Name of the profile file. /// public string ProfileName { get => _profileName; - set - { - if (value == _profileName) - return; - - _profileName = value; - OnPropertyChanged(); - } + set => SetProperty(ref _profileName, value); } /// @@ -78,14 +57,7 @@ public string ProfileName public bool ShowWrongPassword { get => _showWrongPassword; - set - { - if (value == _showWrongPassword) - return; - - _showWrongPassword = value; - OnPropertyChanged(); - } + set => SetProperty(ref _showWrongPassword, value); } /// @@ -113,14 +85,7 @@ public SecureString Password public bool IsPasswordEmpty { get => _isPasswordEmpty; - set - { - if (value == _isPasswordEmpty) - return; - - _isPasswordEmpty = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isPasswordEmpty, value); } /// diff --git a/Source/NETworkManager/ViewModels/CredentialsPasswordViewModel.cs b/Source/NETworkManager/ViewModels/CredentialsPasswordViewModel.cs index d401bbf7a8..5e6ed41ef2 100644 --- a/Source/NETworkManager/ViewModels/CredentialsPasswordViewModel.cs +++ b/Source/NETworkManager/ViewModels/CredentialsPasswordViewModel.cs @@ -1,11 +1,9 @@ using System; using System.Security; -using System.Windows.Input; -using NETworkManager.Utilities; namespace NETworkManager.ViewModels; -public class CredentialsPasswordViewModel : ViewModelBase +public class CredentialsPasswordViewModel : DialogViewModelBase { /// /// Private variable for . @@ -25,21 +23,10 @@ public class CredentialsPasswordViewModel : ViewModelBase /// which is executed on cancel click. public CredentialsPasswordViewModel(Action okCommand, Action cancelHandler) + : base(okCommand, cancelHandler) { - OKCommand = new RelayCommand(_ => okCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); } - /// - /// Command which is called when the OK button is clicked. - /// - public ICommand OKCommand { get; } - - /// - /// Command which is called when the cancel button is clicked. - /// - public ICommand CancelCommand { get; } - /// /// Password as . /// @@ -65,14 +52,7 @@ public SecureString Password public bool IsPasswordEmpty { get => _isPasswordEmpty; - set - { - if (value == _isPasswordEmpty) - return; - - _isPasswordEmpty = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isPasswordEmpty, value); } /// diff --git a/Source/NETworkManager/ViewModels/CredentialsSetPasswordViewModel.cs b/Source/NETworkManager/ViewModels/CredentialsSetPasswordViewModel.cs index 2872d8a21d..1884aebf3d 100644 --- a/Source/NETworkManager/ViewModels/CredentialsSetPasswordViewModel.cs +++ b/Source/NETworkManager/ViewModels/CredentialsSetPasswordViewModel.cs @@ -1,11 +1,10 @@ using System; using System.Security; -using System.Windows.Input; using NETworkManager.Utilities; namespace NETworkManager.ViewModels; -public class CredentialsSetPasswordViewModel : ViewModelBase +public class CredentialsSetPasswordViewModel : DialogViewModelBase { /// /// Private variable for . @@ -35,21 +34,10 @@ public class CredentialsSetPasswordViewModel : ViewModelBase /// which is executed on cancel click. public CredentialsSetPasswordViewModel(Action okCommand, Action cancelHandler) + : base(okCommand, cancelHandler) { - OKCommand = new RelayCommand(_ => okCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); } - /// - /// Command which is called when the OK button is clicked. - /// - public ICommand OKCommand { get; } - - /// - /// Command which is called when the cancel button is clicked. - /// - public ICommand CancelCommand { get; } - /// /// Password as . /// @@ -94,14 +82,7 @@ public SecureString PasswordRepeat public bool IsPasswordEmpty { get => _isPasswordEmpty; - set - { - if (value == _isPasswordEmpty) - return; - - _isPasswordEmpty = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isPasswordEmpty, value); } /// @@ -110,14 +91,7 @@ public bool IsPasswordEmpty public bool IsRepeatedPasswordEqual { get => _isRepeatedPasswordEqual; - set - { - if (value == _isRepeatedPasswordEqual) - return; - - _isRepeatedPasswordEqual = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isRepeatedPasswordEqual, value); } /// From 420e447c91574ff09c1cce805f7f5d757573251a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 12:41:11 +0000 Subject: [PATCH 4/6] Refactor remaining dialog ViewModels and simplify property setters Co-authored-by: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com> --- .../ViewModels/PingMonitorHostViewModel.cs | 78 +++---------------- .../ViewModels/PortProfilesViewModel.cs | 12 +-- .../ViewModels/SNMPOIDProfilesViewModel.cs | 11 +-- 3 files changed, 14 insertions(+), 87 deletions(-) diff --git a/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs b/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs index 0211001a9c..66f62b8075 100644 --- a/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs +++ b/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs @@ -43,14 +43,7 @@ public class PingMonitorHostViewModel : ViewModelBase, IProfileManager public string Host { get => _host; - set - { - if (value == _host) - return; - - _host = value; - OnPropertyChanged(); - } + set => SetProperty(ref _host, value); } public ICollectionView HostHistoryView { get; } @@ -60,14 +53,7 @@ public string Host public bool IsRunning { get => _isRunning; - set - { - if (value == _isRunning) - return; - - _isRunning = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isRunning, value); } private bool _isCanceling; @@ -75,14 +61,7 @@ public bool IsRunning public bool IsCanceling { get => _isCanceling; - set - { - if (value == _isCanceling) - return; - - _isCanceling = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isCanceling, value); } private bool _isStatusMessageDisplayed; @@ -90,14 +69,7 @@ public bool IsCanceling public bool IsStatusMessageDisplayed { get => _isStatusMessageDisplayed; - set - { - if (value == _isStatusMessageDisplayed) - return; - - _isStatusMessageDisplayed = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isStatusMessageDisplayed, value); } private string _statusMessage; @@ -136,14 +108,7 @@ public ObservableCollection Hosts public PingMonitorView SelectedHost { get => _selectedHost; - set - { - if (value == _selectedHost) - return; - - _selectedHost = value; - OnPropertyChanged(); - } + set => SetProperty(ref _selectedHost, value); } #region Profiles @@ -153,14 +118,7 @@ public PingMonitorView SelectedHost public ICollectionView Profiles { get => _profiles; - private set - { - if (value == _profiles) - return; - - _profiles = value; - OnPropertyChanged(); - } + private set => SetProperty(ref _profiles, value); } private ProfileInfo _selectedProfile; @@ -168,14 +126,7 @@ private set public ProfileInfo SelectedProfile { get => _selectedProfile; - set - { - if (value == _selectedProfile) - return; - - _selectedProfile = value; - OnPropertyChanged(); - } + set => SetProperty(ref _selectedProfile, value); } private string _search; @@ -206,14 +157,7 @@ public string Search public bool IsSearching { get => _isSearching; - set - { - if (value == _isSearching) - return; - - _isSearching = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isSearching, value); } private bool _profileFilterIsOpen; @@ -221,10 +165,8 @@ public bool IsSearching public bool ProfileFilterIsOpen { get => _profileFilterIsOpen; - set - { - if (value == _profileFilterIsOpen) - return; + set => SetProperty(ref _profileFilterIsOpen, value); + } _profileFilterIsOpen = value; OnPropertyChanged(); diff --git a/Source/NETworkManager/ViewModels/PortProfilesViewModel.cs b/Source/NETworkManager/ViewModels/PortProfilesViewModel.cs index 03dde8eac0..60874c8a32 100644 --- a/Source/NETworkManager/ViewModels/PortProfilesViewModel.cs +++ b/Source/NETworkManager/ViewModels/PortProfilesViewModel.cs @@ -4,24 +4,20 @@ using System.ComponentModel; using System.Linq; using System.Windows.Data; -using System.Windows.Input; using NETworkManager.Models.Network; using NETworkManager.Settings; -using NETworkManager.Utilities; namespace NETworkManager.ViewModels; -public class PortProfilesViewModel : ViewModelBase +public class PortProfilesViewModel : DialogViewModelBase { private string _search; private IList _selectedPortProfiles = new ArrayList(); public PortProfilesViewModel(Action okCommand, Action cancelHandler) + : base(okCommand, cancelHandler) { - OKCommand = new RelayCommand(_ => okCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); - PortProfiles = CollectionViewSource.GetDefaultView(SettingsManager.Current.PortScanner_PortProfiles); PortProfiles.SortDescriptions.Add( new SortDescription(nameof(PortProfileInfo.Name), ListSortDirection.Ascending)); @@ -41,10 +37,6 @@ public PortProfilesViewModel(Action okCommand, Action _search; diff --git a/Source/NETworkManager/ViewModels/SNMPOIDProfilesViewModel.cs b/Source/NETworkManager/ViewModels/SNMPOIDProfilesViewModel.cs index a5dd9b983b..6298d9360c 100644 --- a/Source/NETworkManager/ViewModels/SNMPOIDProfilesViewModel.cs +++ b/Source/NETworkManager/ViewModels/SNMPOIDProfilesViewModel.cs @@ -1,14 +1,12 @@ using System; using System.ComponentModel; using System.Windows.Data; -using System.Windows.Input; using NETworkManager.Models.Network; using NETworkManager.Settings; -using NETworkManager.Utilities; namespace NETworkManager.ViewModels; -public class SNMPOIDProfilesViewModel : ViewModelBase +public class SNMPOIDProfilesViewModel : DialogViewModelBase { private string _search; @@ -16,10 +14,8 @@ public class SNMPOIDProfilesViewModel : ViewModelBase public SNMPOIDProfilesViewModel(Action okCommand, Action cancelHandler) + : base(okCommand, cancelHandler) { - OKCommand = new RelayCommand(_ => okCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); - OIDProfiles = CollectionViewSource.GetDefaultView(SettingsManager.Current.SNMP_OidProfiles); OIDProfiles.SortDescriptions.Add(new SortDescription(nameof(SNMPOIDProfileInfo.Name), ListSortDirection.Ascending)); @@ -39,9 +35,6 @@ public SNMPOIDProfilesViewModel(Action okCommand, }; } - public ICommand OKCommand { get; } - public ICommand CancelCommand { get; } - public string Search { get => _search; From 804e36645d7fd87b0f51fc24ec4a259852d2ad38 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 12:44:15 +0000 Subject: [PATCH 5/6] Add ConnectDialogViewModelBase and refactor Connect ViewModels Co-authored-by: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com> --- .../ViewModels/ConnectDialogViewModelBase.cs | 33 ++++++++ .../ViewModels/PuTTYConnectViewModel.cs | 12 +-- .../RemoteDesktopConnectViewModel.cs | 75 +++---------------- 3 files changed, 48 insertions(+), 72 deletions(-) create mode 100644 Source/NETworkManager/ViewModels/ConnectDialogViewModelBase.cs diff --git a/Source/NETworkManager/ViewModels/ConnectDialogViewModelBase.cs b/Source/NETworkManager/ViewModels/ConnectDialogViewModelBase.cs new file mode 100644 index 0000000000..addfd781bd --- /dev/null +++ b/Source/NETworkManager/ViewModels/ConnectDialogViewModelBase.cs @@ -0,0 +1,33 @@ +using System; +using System.Windows.Input; +using NETworkManager.Utilities; + +namespace NETworkManager.ViewModels; + +/// +/// Base class for connect dialog ViewModels that have Connect and Cancel commands. +/// +/// The type of the derived ViewModel. +public abstract class ConnectDialogViewModelBase : ViewModelBase where T : ConnectDialogViewModelBase +{ + /// + /// Command executed when Connect button is clicked. + /// + public ICommand ConnectCommand { get; } + + /// + /// Command executed when Cancel button is clicked. + /// + public ICommand CancelCommand { get; } + + /// + /// Initializes a new instance of the class. + /// + /// Action to execute when Connect is clicked. + /// Action to execute when Cancel is clicked. + protected ConnectDialogViewModelBase(Action connectCommand, Action cancelHandler) + { + ConnectCommand = new RelayCommand(_ => connectCommand((T)this)); + CancelCommand = new RelayCommand(_ => cancelHandler((T)this)); + } +} diff --git a/Source/NETworkManager/ViewModels/PuTTYConnectViewModel.cs b/Source/NETworkManager/ViewModels/PuTTYConnectViewModel.cs index 1c71d7aac1..c019054d70 100644 --- a/Source/NETworkManager/ViewModels/PuTTYConnectViewModel.cs +++ b/Source/NETworkManager/ViewModels/PuTTYConnectViewModel.cs @@ -1,14 +1,12 @@ using System; using System.ComponentModel; using System.Windows.Data; -using System.Windows.Input; using NETworkManager.Models.PuTTY; using NETworkManager.Settings; -using NETworkManager.Utilities; namespace NETworkManager.ViewModels; -public class PuTTYConnectViewModel : ViewModelBase +public class PuTTYConnectViewModel : ConnectDialogViewModelBase { private string _additionalCommandLine; @@ -41,10 +39,8 @@ public class PuTTYConnectViewModel : ViewModelBase public PuTTYConnectViewModel(Action connectCommand, Action cancelHandler, string host = null) + : base(connectCommand, cancelHandler) { - ConnectCommand = new RelayCommand(_ => connectCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); - if (!string.IsNullOrEmpty(host)) Host = host; @@ -60,9 +56,7 @@ public PuTTYConnectViewModel(Action connectCommand, LoadSettings(); } - public ICommand ConnectCommand { get; } - - public ICommand CancelCommand { get; } + // Commands are inherited from ConnectDialogViewModelBase public ConnectionMode ConnectionMode { diff --git a/Source/NETworkManager/ViewModels/RemoteDesktopConnectViewModel.cs b/Source/NETworkManager/ViewModels/RemoteDesktopConnectViewModel.cs index fc445710e0..0252922a5c 100644 --- a/Source/NETworkManager/ViewModels/RemoteDesktopConnectViewModel.cs +++ b/Source/NETworkManager/ViewModels/RemoteDesktopConnectViewModel.cs @@ -4,11 +4,10 @@ using System.ComponentModel; using System.Security; using System.Windows.Data; -using System.Windows.Input; namespace NETworkManager.ViewModels; -public class RemoteDesktopConnectViewModel : ViewModelBase +public class RemoteDesktopConnectViewModel : ConnectDialogViewModelBase { #region Variables private bool _connectAs; @@ -16,14 +15,7 @@ public class RemoteDesktopConnectViewModel : ViewModelBase public bool ConnectAs { get => _connectAs; - set - { - if (value == _connectAs) - return; - - _connectAs = value; - OnPropertyChanged(); - } + set => SetProperty(ref _connectAs, value); } private string _name; @@ -31,14 +23,7 @@ public bool ConnectAs public string Name { get => _name; - set - { - if (value == _name) - return; - - _name = value; - OnPropertyChanged(); - } + set => SetProperty(ref _name, value); } private string _host; @@ -46,14 +31,7 @@ public string Name public string Host { get => _host; - set - { - if (value == _host) - return; - - _host = value; - OnPropertyChanged(); - } + set => SetProperty(ref _host, value); } public ICollectionView HostHistoryView { get; } @@ -63,14 +41,7 @@ public string Host public bool UseCredentials { get => _useCredentials; - set - { - if (value == _useCredentials) - return; - - _useCredentials = value; - OnPropertyChanged(); - } + set => SetProperty(ref _useCredentials, value); } private string _domain; @@ -78,6 +49,8 @@ public bool UseCredentials public string Domain { get => _domain; + set => SetProperty(ref _domain, value); + } set { if (value == _domain) @@ -93,14 +66,7 @@ public string Domain public string Username { get => _username; - set - { - if (value == _username) - return; - - _username = value; - OnPropertyChanged(); - } + set => SetProperty(ref _username, value); } private bool _isPasswordEmpty = true; @@ -108,14 +74,7 @@ public string Username public bool IsPasswordEmpty { get => _isPasswordEmpty; - set - { - if (value == _isPasswordEmpty) - return; - - _isPasswordEmpty = value; - OnPropertyChanged(); - } + set => SetProperty(ref _isPasswordEmpty, value); } private SecureString _password = new(); @@ -141,14 +100,7 @@ public SecureString Password public bool AdminSession { get => _adminSession; - set - { - if (value == _adminSession) - return; - - _adminSession = value; - OnPropertyChanged(); - } + set => SetProperty(ref _adminSession, value); } #endregion @@ -156,10 +108,8 @@ public bool AdminSession public RemoteDesktopConnectViewModel(Action connectCommand, Action cancelHandler, (string Name, string Host, bool AdminSession)? connectAsOptions = null) + : base(connectCommand, cancelHandler) { - ConnectCommand = new RelayCommand(_ => connectCommand(this)); - CancelCommand = new RelayCommand(_ => cancelHandler(this)); - if (connectAsOptions == null) { HostHistoryView = CollectionViewSource.GetDefaultView(SettingsManager.Current.RemoteDesktop_HostHistory); @@ -180,8 +130,7 @@ public RemoteDesktopConnectViewModel(Action conne #endregion #region Commands - - public ICommand ConnectCommand { get; } + // Commands are inherited from ConnectDialogViewModelBase public ICommand CancelCommand { get; } #endregion From a9f829656eaf7c5542a337e43a3f1da5ad33b4fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 12:46:28 +0000 Subject: [PATCH 6/6] Fix code review issues: Remove duplicate code fragments Co-authored-by: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com> --- .../ViewModels/PingMonitorHostViewModel.cs | 5 ----- .../ViewModels/RemoteDesktopConnectViewModel.cs | 11 ----------- 2 files changed, 16 deletions(-) diff --git a/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs b/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs index 66f62b8075..a63dda9a07 100644 --- a/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs +++ b/Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs @@ -168,11 +168,6 @@ public bool ProfileFilterIsOpen set => SetProperty(ref _profileFilterIsOpen, value); } - _profileFilterIsOpen = value; - OnPropertyChanged(); - } - } - public ICollectionView ProfileFilterTagsView { get; } private ObservableCollection ProfileFilterTags { get; } = []; diff --git a/Source/NETworkManager/ViewModels/RemoteDesktopConnectViewModel.cs b/Source/NETworkManager/ViewModels/RemoteDesktopConnectViewModel.cs index 0252922a5c..f7c4552b9f 100644 --- a/Source/NETworkManager/ViewModels/RemoteDesktopConnectViewModel.cs +++ b/Source/NETworkManager/ViewModels/RemoteDesktopConnectViewModel.cs @@ -51,15 +51,6 @@ public string Domain get => _domain; set => SetProperty(ref _domain, value); } - set - { - if (value == _domain) - return; - - _domain = value; - OnPropertyChanged(); - } - } private string _username; @@ -131,8 +122,6 @@ public RemoteDesktopConnectViewModel(Action conne #region Commands // Commands are inherited from ConnectDialogViewModelBase - - public ICommand CancelCommand { get; } #endregion #region Methods