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