Projects STRLCPY NETworkManager Commits 6573d76b
🤬
  • Chore: Use .NET 7 syntax (#2003)

    * Chore: Use .NET 7 syntax
    
    * Chore: Make readonly
    
    * Chore: Use .NET 7 syntax
    
    * Chore: Use .NET 7 syntax
    
    * Chore: Use .NET 7 syntax
    
    * Chore: Use .NET 7 syntax
    
    * Chore: Use .NET 7 syntax
    
    * Chore: Use .NET 7 syntax
    
    * Chore: Use .NET 7 syntax
    
    * Chore: Use .NET 7 syntax
    
    * Chore: Use .NET 7 syntax
  • Loading...
  • BornToBeRoot committed with GitHub 1 year ago
    6573d76b
    1 parent 1b29bb41
Showing first 20 files as there are too many
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/App.xaml.cs
    skipped 10 lines
    11 11  using System.IO;
    12 12  using log4net;
    13 13   
    14  -namespace NETworkManager
     14 +namespace NETworkManager;
     15 + 
     16 +/*
     17 + * Class: App
     18 + * 1) Get command line args
     19 + * 2) Detect current configuration
     20 + * 3) Get assembly info
     21 + * 4) Load settings
     22 + * 5) Load localization / language
     23 + *
     24 + * Class: MainWindow
     25 + * 6) Load appearance
     26 + * 7) Load profiles
     27 + */
     28 + 
     29 +public partial class App
    15 30  {
    16  - /*
    17  - * Class: App
    18  - * 1) Get command line args
    19  - * 2) Detect current configuration
    20  - * 3) Get assembly info
    21  - * 4) Load settings
    22  - * 5) Load localization / language
    23  - *
    24  - * Class: MainWindow
    25  - * 6) Load appearance
    26  - * 7) Load profiles
    27  - */
     31 + private static readonly ILog _log = LogManager.GetLogger(typeof(App));
    28 32   
    29  - public partial class App
    30  - {
    31  - private static readonly ILog _log = LogManager.GetLogger(typeof(App));
     33 + // Single instance identifier
     34 + private const string GUID = "6A3F34B2-161F-4F70-A8BC-A19C40F79CFB";
     35 + private Mutex _mutex;
     36 + private DispatcherTimer _dispatcherTimer;
    32 37   
    33  - // Single instance identifier
    34  - private const string GUID = "6A3F34B2-161F-4F70-A8BC-A19C40F79CFB";
    35  - private Mutex _mutex;
    36  - private DispatcherTimer _dispatcherTimer;
     38 + private bool _singleInstanceClose;
    37 39   
    38  - private bool _singleInstanceClose;
     40 + public App()
     41 + {
     42 + ShutdownMode = ShutdownMode.OnMainWindowClose;
     43 + }
    39 44   
    40  - public App()
    41  - {
    42  - ShutdownMode = ShutdownMode.OnMainWindowClose;
    43  - }
    44  - 
    45  - private void Application_Startup(object sender, StartupEventArgs e)
    46  - {
    47  - var startLog = $@"
     45 + private void Application_Startup(object sender, StartupEventArgs e)
     46 + {
     47 + var startLog = $@"
    48 48   _ _ _____ _____ _ __ __
    49 49   | \ | | ____|_ _|_ _____ _ __| | _| \/ | __ _ _ __ __ _ __ _ ___ _ __
    50 50   | \| | _| | | \ \ /\ / / _ \| '__| |/ / |\/| |/ _` | '_ \ / _` |/ _` |/ _ \ '__|
    skipped 6 lines
    57 57   
    58 58   Version: {AssemblyManager.Current.Version}
    59 59  ";
    60  - _log.Info(startLog);
     60 + _log.Info(startLog);
    61 61   
    62  - // Catch unhandled exception globally
    63  - AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
    64  - {
    65  - _log.Fatal("Unhandled exception occured!");
     62 + // Catch unhandled exception globally
     63 + AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
     64 + {
     65 + _log.Fatal("Unhandled exception occured!");
    66 66   
    67  - if (e.ExceptionObject != null)
    68  - _log.Fatal($"Exception raised by: {e.ExceptionObject}");
    69  - };
     67 + if (e.ExceptionObject != null)
     68 + _log.Fatal($"Exception raised by: {e.ExceptionObject}");
     69 + };
    70 70   
    71  - // If we have restart our application... wait until it has finished
    72  - if (CommandLineManager.Current.RestartPid != -1)
    73  - {
    74  - _log.Info($"Waiting for another NETworkManager process with Pid {CommandLineManager.Current.RestartPid} to exit...");
     71 + // If we have restart our application... wait until it has finished
     72 + if (CommandLineManager.Current.RestartPid != -1)
     73 + {
     74 + _log.Info($"Waiting for another NETworkManager process with Pid {CommandLineManager.Current.RestartPid} to exit...");
     75 + 
     76 + var processList = Process.GetProcesses();
     77 + var process = processList.FirstOrDefault(x => x.Id == CommandLineManager.Current.RestartPid);
     78 + process?.WaitForExit();
     79 + 
     80 + _log.Info($"NETworkManager process with Pid {CommandLineManager.Current.RestartPid} has been exited.");
     81 + }
    75 82   
    76  - var processList = Process.GetProcesses();
    77  - var process = processList.FirstOrDefault(x => x.Id == CommandLineManager.Current.RestartPid);
    78  - process?.WaitForExit();
     83 + MigrateAppDataToDocuments();
    79 84   
    80  - _log.Info($"NETworkManager process with Pid {CommandLineManager.Current.RestartPid} has been exited.");
    81  - }
     85 + // Load settings
     86 + try
     87 + {
     88 + _log.Info("Application settings are being loaded...");
    82 89   
    83  - MigrateAppDataToDocuments();
     90 + if (CommandLineManager.Current.ResetSettings)
     91 + SettingsManager.InitDefault();
     92 + else
     93 + SettingsManager.Load();
     94 + }
     95 + catch (InvalidOperationException ex)
     96 + {
     97 + _log.Error("Could not load application settings!");
     98 + _log.Error(ex.Message + "-" + ex.StackTrace);
    84 99   
    85  - // Load settings
    86  - try
    87  - {
    88  - _log.Info("Application settings are being loaded...");
     100 + // Create backup of corrupted file
     101 + var destinationFile = $"{TimestampHelper.GetTimestamp()}_corrupted_" + SettingsManager.GetSettingsFileName();
     102 + File.Copy(SettingsManager.GetSettingsFilePath(), Path.Combine(SettingsManager.GetSettingsFolderLocation(), destinationFile));
     103 + _log.Info($"A backup of the corrupted settings file has been saved under {destinationFile}");
    89 104   
    90  - if (CommandLineManager.Current.ResetSettings)
    91  - SettingsManager.InitDefault();
    92  - else
    93  - SettingsManager.Load();
    94  - }
    95  - catch (InvalidOperationException ex)
    96  - {
    97  - _log.Error("Could not load application settings!");
    98  - _log.Error(ex.Message + "-" + ex.StackTrace);
     105 + // Initialize default application settings
     106 + _log.Info("Initialize default application settings...");
    99 107   
    100  - // Create backup of corrupted file
    101  - var destinationFile = $"{TimestampHelper.GetTimestamp()}_corrupted_" + SettingsManager.GetSettingsFileName();
    102  - File.Copy(SettingsManager.GetSettingsFilePath(), Path.Combine(SettingsManager.GetSettingsFolderLocation(), destinationFile));
    103  - _log.Info($"A backup of the corrupted settings file has been saved under {destinationFile}");
     108 + SettingsManager.InitDefault();
     109 + ConfigurationManager.Current.ShowSettingsResetNoteOnStartup = true;
     110 + }
    104 111   
    105  - // Initialize default application settings
    106  - _log.Info("Initialize default application settings...");
     112 + // Perform settings update if settings version is lower than application version
     113 + if (SettingsManager.Current.FirstRun || string.IsNullOrEmpty(SettingsManager.Current.Version))
     114 + {
     115 + _log.Info($"Application settings version is empty and will be set to {AssemblyManager.Current.Version}.");
    107 116   
    108  - SettingsManager.InitDefault();
    109  - ConfigurationManager.Current.ShowSettingsResetNoteOnStartup = true;
    110  - }
     117 + SettingsManager.Current.Version = AssemblyManager.Current.Version.ToString();
     118 + }
     119 + else
     120 + {
     121 + Version settingsVersion = Version.Parse(SettingsManager.Current.Version);
    111 122   
    112  - // Perform settings update if settings version is lower than application version
    113  - if (SettingsManager.Current.FirstRun || string.IsNullOrEmpty(SettingsManager.Current.Version))
     123 + if (settingsVersion < AssemblyManager.Current.Version)
    114 124   {
    115  - _log.Info($"Application settings version is empty and will be set to {AssemblyManager.Current.Version}.");
     125 + _log.Info($"Application settings are on version {settingsVersion} and will be upgraded to {AssemblyManager.Current.Version}");
     126 + 
     127 + SettingsManager.Upgrade(settingsVersion, AssemblyManager.Current.Version);
    116 128   
    117  - SettingsManager.Current.Version = AssemblyManager.Current.Version.ToString();
     129 + _log.Info($"Application settings upgraded to version {AssemblyManager.Current.Version}");
    118 130   }
    119 131   else
    120 132   {
    121  - Version settingsVersion = Version.Parse(SettingsManager.Current.Version);
    122  - 
    123  - if (settingsVersion < AssemblyManager.Current.Version)
    124  - {
    125  - _log.Info($"Application settings are on version {settingsVersion} and will be upgraded to {AssemblyManager.Current.Version}");
    126  - 
    127  - SettingsManager.Upgrade(settingsVersion, AssemblyManager.Current.Version);
    128  - 
    129  - _log.Info($"Application settings upgraded to version {AssemblyManager.Current.Version}");
    130  - }
    131  - else
    132  - {
    133  - _log.Info($"Application settings are already on version {AssemblyManager.Current.Version}.");
    134  - }
     133 + _log.Info($"Application settings are already on version {AssemblyManager.Current.Version}.");
    135 134   }
     135 + }
    136 136   
    137  - // Init the location with the culture code...
    138  - var localizationManager = LocalizationManager.GetInstance(SettingsManager.Current.Localization_CultureCode);
    139  - Localization.Resources.Strings.Culture = localizationManager.Culture;
     137 + // Init the location with the culture code...
     138 + var localizationManager = LocalizationManager.GetInstance(SettingsManager.Current.Localization_CultureCode);
     139 + Localization.Resources.Strings.Culture = localizationManager.Culture;
    140 140   
    141  - _log.Info($"Application localization culture has been set to {localizationManager.Current.Code} (Settings value is \"{SettingsManager.Current.Localization_CultureCode}\").");
     141 + _log.Info($"Application localization culture has been set to {localizationManager.Current.Code} (Settings value is \"{SettingsManager.Current.Localization_CultureCode}\").");
    142 142   
    143  - // Show help window
    144  - if (CommandLineManager.Current.Help)
    145  - {
    146  - _log.Info("Set StartupUri to CommandLineWindow.xaml...");
    147  - StartupUri = new Uri("CommandLineWindow.xaml", UriKind.Relative);
     143 + // Show help window
     144 + if (CommandLineManager.Current.Help)
     145 + {
     146 + _log.Info("Set StartupUri to CommandLineWindow.xaml...");
     147 + StartupUri = new Uri("CommandLineWindow.xaml", UriKind.Relative);
    148 148   
    149  - return;
    150  - }
     149 + return;
     150 + }
    151 151   
    152  - // Create mutex
    153  - _log.Info($"Try to acquire mutex with GUID {GUID} for single instance detection...");
     152 + // Create mutex
     153 + _log.Info($"Try to acquire mutex with GUID {GUID} for single instance detection...");
    154 154   
    155  - _mutex = new Mutex(true, "{" + GUID + "}");
    156  - var mutexIsAcquired = _mutex.WaitOne(TimeSpan.Zero, true);
     155 + _mutex = new Mutex(true, "{" + GUID + "}");
     156 + var mutexIsAcquired = _mutex.WaitOne(TimeSpan.Zero, true);
    157 157   
    158  - _log.Info($"Mutex value for {GUID} is {mutexIsAcquired}");
     158 + _log.Info($"Mutex value for {GUID} is {mutexIsAcquired}");
    159 159   
    160  - // Release mutex
    161  - if (mutexIsAcquired)
    162  - _mutex.ReleaseMutex();
     160 + // Release mutex
     161 + if (mutexIsAcquired)
     162 + _mutex.ReleaseMutex();
    163 163   
    164  - if (mutexIsAcquired || SettingsManager.Current.Window_MultipleInstances)
     164 + if (mutexIsAcquired || SettingsManager.Current.Window_MultipleInstances)
     165 + {
     166 + if (SettingsManager.Current.General_BackgroundJobInterval != 0)
    165 167   {
    166  - if (SettingsManager.Current.General_BackgroundJobInterval != 0)
    167  - {
    168  - _log.Info($"Setup background job with interval {SettingsManager.Current.General_BackgroundJobInterval} minute(s)...");
     168 + _log.Info($"Setup background job with interval {SettingsManager.Current.General_BackgroundJobInterval} minute(s)...");
    169 169   
    170  - _dispatcherTimer = new DispatcherTimer
    171  - {
    172  - Interval = TimeSpan.FromMinutes(SettingsManager.Current.General_BackgroundJobInterval)
    173  - };
    174  - _dispatcherTimer.Tick += DispatcherTimer_Tick;
    175  - _dispatcherTimer.Start();
    176  - }
    177  - else
     170 + _dispatcherTimer = new DispatcherTimer
    178 171   {
    179  - _log.Info("Background job is disabled.");
    180  - }
    181  - 
    182  - // Show splash screen
    183  - if (SettingsManager.Current.SplashScreen_Enabled)
    184  - {
    185  - _log.Info("Show SplashScreen while application is loading...");
    186  - new SplashScreen(@"SplashScreen.png").Show(true, true);
    187  - }
    188  - 
    189  - // Show main window
    190  - _log.Info("Set StartupUri to MainWindow.xaml...");
    191  - StartupUri = new Uri("MainWindow.xaml", UriKind.Relative);
     172 + Interval = TimeSpan.FromMinutes(SettingsManager.Current.General_BackgroundJobInterval)
     173 + };
     174 + _dispatcherTimer.Tick += DispatcherTimer_Tick;
     175 + _dispatcherTimer.Start();
    192 176   }
    193 177   else
    194 178   {
    195  - // Bring the already running application into the foreground
    196  - _log.Info("Another NETworkManager process is already running. Try to bring the window to the foreground...");
    197  - SingleInstance.PostMessage((IntPtr)SingleInstance.HWND_BROADCAST, SingleInstance.WM_SHOWME, IntPtr.Zero, IntPtr.Zero);
     179 + _log.Info("Background job is disabled.");
     180 + }
    198 181   
    199  - // Close the application
    200  - _singleInstanceClose = true;
    201  - Shutdown();
     182 + // Show splash screen
     183 + if (SettingsManager.Current.SplashScreen_Enabled)
     184 + {
     185 + _log.Info("Show SplashScreen while application is loading...");
     186 + new SplashScreen(@"SplashScreen.png").Show(true, true);
    202 187   }
     188 + 
     189 + // Show main window
     190 + _log.Info("Set StartupUri to MainWindow.xaml...");
     191 + StartupUri = new Uri("MainWindow.xaml", UriKind.Relative);
    203 192   }
     193 + else
     194 + {
     195 + // Bring the already running application into the foreground
     196 + _log.Info("Another NETworkManager process is already running. Try to bring the window to the foreground...");
     197 + SingleInstance.PostMessage((IntPtr)SingleInstance.HWND_BROADCAST, SingleInstance.WM_SHOWME, IntPtr.Zero, IntPtr.Zero);
    204 198   
    205  - [Obsolete("Temp method to migrate settings and profiles... should be removed after in 2-3 updates.")]
    206  - private void MigrateAppDataToDocuments()
     199 + // Close the application
     200 + _singleInstanceClose = true;
     201 + Shutdown();
     202 + }
     203 + }
     204 + 
     205 + [Obsolete("Temp method to migrate settings and profiles... should be removed after in 2-3 updates.")]
     206 + private void MigrateAppDataToDocuments()
     207 + {
     208 + // Migrate settings and profiles from old paths to new paths
     209 + if (!ConfigurationManager.Current.IsPortable)
    207 210   {
    208  - // Migrate settings and profiles from old paths to new paths
    209  - if (!ConfigurationManager.Current.IsPortable)
     211 + string oldSettingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "NETworkManager", "Settings");
     212 + 
     213 + if (Directory.Exists(oldSettingsPath))
    210 214   {
    211  - string oldSettingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "NETworkManager", "Settings");
     215 + string oldSettingsFile = Path.Combine(oldSettingsPath, "Settings.xml");
    212 216   
    213  - if (Directory.Exists(oldSettingsPath))
     217 + var oldSettingsError = false;
     218 + 
     219 + if (File.Exists(oldSettingsFile))
    214 220   {
    215  - string oldSettingsFile = Path.Combine(oldSettingsPath, "Settings.xml");
    216  - 
    217  - var oldSettingsError = false;
    218  - 
    219  - if (File.Exists(oldSettingsFile))
    220  - {
    221  - _log.Info($"Migrate settings file from \"{oldSettingsFile}\" to \"{SettingsManager.GetSettingsFilePath()}\"...");
    222  - Directory.CreateDirectory(SettingsManager.GetSettingsFolderLocation());
    223  - 
    224  - try
    225  - {
    226  - File.Move(oldSettingsFile, SettingsManager.GetSettingsFilePath());
    227  - }
    228  - catch (Exception ex)
    229  - {
    230  - oldSettingsError = true;
    231  - _log.Error("Could not migrate settings file!", ex);
    232  - }
    233  - }
     221 + _log.Info($"Migrate settings file from \"{oldSettingsFile}\" to \"{SettingsManager.GetSettingsFilePath()}\"...");
     222 + Directory.CreateDirectory(SettingsManager.GetSettingsFolderLocation());
    234 223   
    235 224   try
    236 225   {
    237  - if (!oldSettingsError)
    238  - {
    239  - _log.Info($"Delete folder \"{oldSettingsPath}\"...");
    240  - Directory.Delete(oldSettingsPath, true);
    241  - }
     226 + File.Move(oldSettingsFile, SettingsManager.GetSettingsFilePath());
    242 227   }
    243 228   catch (Exception ex)
    244 229   {
    245  - _log.Error($"Could not delete folder!", ex);
     230 + oldSettingsError = true;
     231 + _log.Error("Could not migrate settings file!", ex);
    246 232   }
    247 233   }
    248 234   
    249  - string oldProfilesPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "NETworkManager", "Profiles");
    250  - 
    251  - if (Directory.Exists(oldProfilesPath))
     235 + try
     236 + {
     237 + if (!oldSettingsError)
     238 + {
     239 + _log.Info($"Delete folder \"{oldSettingsPath}\"...");
     240 + Directory.Delete(oldSettingsPath, true);
     241 + }
     242 + }
     243 + catch (Exception ex)
    252 244   {
    253  - var profileExtensions = new[] { ".xml", ".encrypted" };
     245 + _log.Error($"Could not delete folder!", ex);
     246 + }
     247 + }
    254 248   
    255  - var oldProfileFilePaths = Directory.EnumerateFiles(oldProfilesPath, "*.*", SearchOption.TopDirectoryOnly)
    256  - .Where(f => profileExtensions.Contains(Path.GetExtension(f).ToLowerInvariant()));
     249 + string oldProfilesPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "NETworkManager", "Profiles");
    257 250   
    258  - var oldProfilesError = false;
    259  - 
    260  - if (oldProfileFilePaths != null && oldProfileFilePaths.Count() > 0)
    261  - {
    262  - _log.Info($"Migrate \"{oldProfileFilePaths.Count()}\" profile(s)...");
    263  - var newProfilesPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "NETworkManager", "Profiles");
    264  - Directory.CreateDirectory(newProfilesPath);
     251 + if (Directory.Exists(oldProfilesPath))
     252 + {
     253 + var profileExtensions = new[] { ".xml", ".encrypted" };
    265 254   
    266  - foreach (var oldProfileFilePath in oldProfileFilePaths)
    267  - {
    268  - var newProfileFilePath = Path.Combine(newProfilesPath, Path.GetFileName(oldProfileFilePath));
     255 + var oldProfileFilePaths = Directory.EnumerateFiles(oldProfilesPath, "*.*", SearchOption.TopDirectoryOnly)
     256 + .Where(f => profileExtensions.Contains(Path.GetExtension(f).ToLowerInvariant()));
    269 257   
    270  - _log.Info($"Migrate profile file from \"{oldProfileFilePath}\" to \"{newProfileFilePath}\"");
     258 + var oldProfilesError = false;
    271 259   
    272  - try
    273  - {
    274  - File.Move(oldProfileFilePath, newProfileFilePath);
    275  - }
    276  - catch (Exception ex)
    277  - {
    278  - oldProfilesError = true;
    279  - _log.Error("Could not migrate profile file!", ex);
    280  - }
    281  - }
    282  - }
     260 + if (oldProfileFilePaths != null && oldProfileFilePaths.Count() > 0)
     261 + {
     262 + _log.Info($"Migrate \"{oldProfileFilePaths.Count()}\" profile(s)...");
     263 + var newProfilesPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "NETworkManager", "Profiles");
     264 + Directory.CreateDirectory(newProfilesPath);
    283 265   
    284  - try
     266 + foreach (var oldProfileFilePath in oldProfileFilePaths)
    285 267   {
    286  - if (!oldProfilesError)
     268 + var newProfileFilePath = Path.Combine(newProfilesPath, Path.GetFileName(oldProfileFilePath));
     269 + 
     270 + _log.Info($"Migrate profile file from \"{oldProfileFilePath}\" to \"{newProfileFilePath}\"");
     271 + 
     272 + try
     273 + {
     274 + File.Move(oldProfileFilePath, newProfileFilePath);
     275 + }
     276 + catch (Exception ex)
    287 277   {
    288  - _log.Info($"Delete folder \"{oldProfilesPath}\"...");
    289  - Directory.Delete(oldProfilesPath, true);
     278 + oldProfilesError = true;
     279 + _log.Error("Could not migrate profile file!", ex);
    290 280   }
    291 281   }
    292  - catch (Exception ex)
     282 + }
     283 + 
     284 + try
     285 + {
     286 + if (!oldProfilesError)
    293 287   {
    294  - _log.Error($"Could not delete folder!", ex);
     288 + _log.Info($"Delete folder \"{oldProfilesPath}\"...");
     289 + Directory.Delete(oldProfilesPath, true);
    295 290   }
    296 291   }
     292 + catch (Exception ex)
     293 + {
     294 + _log.Error($"Could not delete folder!", ex);
     295 + }
    297 296   }
    298 297   }
     298 + }
    299 299   
    300  - private void DispatcherTimer_Tick(object sender, EventArgs e)
    301  - {
    302  - _log.Info("Run background job...");
     300 + private void DispatcherTimer_Tick(object sender, EventArgs e)
     301 + {
     302 + _log.Info("Run background job...");
     303 + 
     304 + Save();
     305 + }
    303 306   
    304  - Save();
    305  - }
     307 + protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
     308 + {
     309 + base.OnSessionEnding(e);
    306 310   
    307  - protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
    308  - {
    309  - base.OnSessionEnding(e);
     311 + e.Cancel = true;
    310 312   
    311  - e.Cancel = true;
     313 + Shutdown();
     314 + }
    312 315   
    313  - Shutdown();
    314  - }
     316 + private void Application_Exit(object sender, ExitEventArgs e)
     317 + {
     318 + _log.Info("Exiting NETworkManager...");
    315 319   
    316  - private void Application_Exit(object sender, ExitEventArgs e)
    317  - {
    318  - _log.Info("Exiting NETworkManager...");
     320 + // Save settings, when the application is normally closed
     321 + if (_singleInstanceClose || CommandLineManager.Current.Help)
     322 + return;
    319 323   
    320  - // Save settings, when the application is normally closed
    321  - if (_singleInstanceClose || CommandLineManager.Current.Help)
    322  - return;
     324 + _log.Info("Stop background job (if it exists)...");
     325 + _dispatcherTimer?.Stop();
    323 326   
    324  - _log.Info("Stop background job (if it exists)...");
    325  - _dispatcherTimer?.Stop();
     327 + Save();
     328 + _log.Info("Bye!");
     329 + }
    326 330   
    327  - Save();
    328  - _log.Info("Bye!");
     331 + private void Save()
     332 + {
     333 + if (SettingsManager.Current.SettingsChanged && !ConfigurationManager.Current.DisableSaveSettings)
     334 + {
     335 + _log.Info("Save application settings...");
     336 + SettingsManager.Save();
    329 337   }
    330 338   
    331  - private void Save()
     339 + if (ProfileManager.ProfilesChanged)
    332 340   {
    333  - if (SettingsManager.Current.SettingsChanged && !ConfigurationManager.Current.DisableSaveSettings)
    334  - {
    335  - _log.Info("Save application settings...");
    336  - SettingsManager.Save();
    337  - }
    338  - 
    339  - if (ProfileManager.ProfilesChanged)
    340  - {
    341  - _log.Info("Save current profiles...");
    342  - ProfileManager.Save();
    343  - }
     341 + _log.Info("Save current profiles...");
     342 + ProfileManager.Save();
    344 343   }
    345 344   }
    346 345  }
    skipped 1 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/CommandLineWindow.xaml.cs
    1 1  using NETworkManager.ViewModels;
    2 2   
    3  -namespace NETworkManager
     3 +namespace NETworkManager;
     4 + 
     5 +// ReSharper disable once UnusedMember.Global, called from App.xaml.cs
     6 +public partial class CommandLineWindow
    4 7  {
    5  - // ReSharper disable once UnusedMember.Global, called from App.xaml.cs
    6  - public partial class CommandLineWindow
     8 + private readonly CommandLineViewModel _viewModel = new CommandLineViewModel();
     9 + 
     10 + public CommandLineWindow()
    7 11   {
    8  - private readonly CommandLineViewModel _viewModel = new CommandLineViewModel();
     12 + InitializeComponent();
     13 + DataContext = _viewModel;
     14 + }
    9 15   
    10  - public CommandLineWindow()
    11  - {
    12  - InitializeComponent();
    13  - DataContext = _viewModel;
    14  - }
    15  - 
    16  - private void Click(object sender, System.Windows.RoutedEventArgs e)
    17  - {
    18  - Close();
    19  - }
     16 + private void Click(object sender, System.Windows.RoutedEventArgs e)
     17 + {
     18 + Close();
    20 19   }
    21 20  }
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/AWSSessionManagerControl.xaml.cs
    skipped 12 lines
    13 13  using NETworkManager.Settings;
    14 14  using NETworkManager.Models.AWS;
    15 15   
    16  -namespace NETworkManager.Controls
     16 +namespace NETworkManager.Controls;
     17 + 
     18 +public partial class AWSSessionManagerControl : INotifyPropertyChanged
    17 19  {
    18  - public partial class AWSSessionManagerControl : INotifyPropertyChanged
     20 + #region PropertyChangedEventHandler
     21 + public event PropertyChangedEventHandler PropertyChanged;
     22 + 
     23 + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    19 24   {
    20  - #region PropertyChangedEventHandler
    21  - public event PropertyChangedEventHandler PropertyChanged;
     25 + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     26 + }
     27 + #endregion
    22 28   
    23  - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    24  - {
    25  - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    26  - }
    27  - #endregion
     29 + #region Variables
     30 + private bool _initialized;
     31 + private bool _closing; // When the tab is closed --> OnClose()
    28 32   
    29  - #region Variables
    30  - private bool _initialized;
    31  - private bool _closing; // When the tab is closed --> OnClose()
     33 + private readonly IDialogCoordinator _dialogCoordinator;
    32 34   
    33  - private readonly IDialogCoordinator _dialogCoordinator;
     35 + private readonly AWSSessionManagerSessionInfo _sessionInfo;
    34 36   
    35  - private readonly AWSSessionManagerSessionInfo _sessionInfo;
     37 + private Process _process;
     38 + private IntPtr _appWin;
    36 39   
    37  - private Process _process;
    38  - private IntPtr _appWin;
    39  - 
    40  - private bool _isConnected;
    41  - public bool IsConnected
     40 + private bool _isConnected;
     41 + public bool IsConnected
     42 + {
     43 + get => _isConnected;
     44 + set
    42 45   {
    43  - get => _isConnected;
    44  - set
    45  - {
    46  - if (value == _isConnected)
    47  - return;
     46 + if (value == _isConnected)
     47 + return;
    48 48   
    49  - _isConnected = value;
    50  - OnPropertyChanged();
    51  - }
     49 + _isConnected = value;
     50 + OnPropertyChanged();
    52 51   }
     52 + }
    53 53   
    54  - private bool _isConnecting;
    55  - public bool IsConnecting
     54 + private bool _isConnecting;
     55 + public bool IsConnecting
     56 + {
     57 + get => _isConnecting;
     58 + set
    56 59   {
    57  - get => _isConnecting;
    58  - set
    59  - {
    60  - if (value == _isConnecting)
    61  - return;
     60 + if (value == _isConnecting)
     61 + return;
    62 62   
    63  - _isConnecting = value;
    64  - OnPropertyChanged();
    65  - }
     63 + _isConnecting = value;
     64 + OnPropertyChanged();
    66 65   }
    67  - #endregion
     66 + }
     67 + #endregion
    68 68   
    69  - #region Constructor, load
    70  - public AWSSessionManagerControl(AWSSessionManagerSessionInfo info)
    71  - {
    72  - InitializeComponent();
    73  - DataContext = this;
     69 + #region Constructor, load
     70 + public AWSSessionManagerControl(AWSSessionManagerSessionInfo info)
     71 + {
     72 + InitializeComponent();
     73 + DataContext = this;
    74 74   
    75  - _dialogCoordinator = DialogCoordinator.Instance;
     75 + _dialogCoordinator = DialogCoordinator.Instance;
    76 76   
    77  - _sessionInfo = info;
     77 + _sessionInfo = info;
    78 78   
    79  - Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
    80  - }
     79 + Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
     80 + }
    81 81   
    82  - private void UserControl_Loaded(object sender, RoutedEventArgs e)
    83  - {
    84  - // Connect after the control is drawn and only on the first init
    85  - if (_initialized)
    86  - return;
     82 + private void UserControl_Loaded(object sender, RoutedEventArgs e)
     83 + {
     84 + // Connect after the control is drawn and only on the first init
     85 + if (_initialized)
     86 + return;
    87 87   
    88  - // Fix: The control is not visible by default, thus height and width is not set. If the values are not set, the size does not scale properly
    89  - WindowHost.Height = (int)ActualHeight;
    90  - WindowHost.Width = (int)ActualWidth;
     88 + // Fix: The control is not visible by default, thus height and width is not set. If the values are not set, the size does not scale properly
     89 + WindowHost.Height = (int)ActualHeight;
     90 + WindowHost.Width = (int)ActualWidth;
    91 91   
    92  - Connect();
    93  - _initialized = true;
    94  - }
     92 + Connect();
     93 + _initialized = true;
     94 + }
    95 95   
    96  - private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
    97  - {
    98  - CloseTab();
    99  - }
    100  - #endregion
     96 + private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
     97 + {
     98 + CloseTab();
     99 + }
     100 + #endregion
    101 101   
    102  - #region ICommands & Actions
    103  - public ICommand ReconnectCommand
    104  - {
    105  - get { return new RelayCommand(p => ReconnectAction()); }
    106  - }
     102 + #region ICommands & Actions
     103 + public ICommand ReconnectCommand
     104 + {
     105 + get { return new RelayCommand(p => ReconnectAction()); }
     106 + }
    107 107   
    108  - private void ReconnectAction()
     108 + private void ReconnectAction()
     109 + {
     110 + Reconnect();
     111 + }
     112 + #endregion
     113 + 
     114 + #region Methods
     115 + private async Task Connect()
     116 + {
     117 + IsConnecting = true;
     118 + 
     119 + var info = new ProcessStartInfo
    109 120   {
    110  - Reconnect();
    111  - }
    112  - #endregion
     121 + FileName = _sessionInfo.ApplicationFilePath,
     122 + Arguments = AWSSessionManager.BuildCommandLine(_sessionInfo)
     123 + };
    113 124   
    114  - #region Methods
    115  - private async Task Connect()
     125 + try
    116 126   {
    117  - IsConnecting = true;
     127 + _process = Process.Start(info);
    118 128   
    119  - var info = new ProcessStartInfo
     129 + if (_process != null)
    120 130   {
    121  - FileName = _sessionInfo.ApplicationFilePath,
    122  - Arguments = AWSSessionManager.BuildCommandLine(_sessionInfo)
    123  - };
     131 + _process.EnableRaisingEvents = true;
     132 + _process.Exited += Process_Exited;
    124 133   
    125  - try
    126  - {
    127  - _process = Process.Start(info);
     134 + // Embed window into panel, remove border etc.
     135 + // _process.WaitForInputIdle();
     136 + _appWin = _process.MainWindowHandle;
    128 137   
    129  - if (_process != null)
     138 + if (_appWin == IntPtr.Zero)
    130 139   {
    131  - _process.EnableRaisingEvents = true;
    132  - _process.Exited += Process_Exited;
     140 + var startTime = DateTime.Now;
    133 141   
    134  - // Embed window into panel, remove border etc.
    135  - // _process.WaitForInputIdle();
    136  - _appWin = _process.MainWindowHandle;
    137  - 
    138  - if (_appWin == IntPtr.Zero)
     142 + while ((DateTime.Now - startTime).TotalSeconds < 10)
    139 143   {
    140  - var startTime = DateTime.Now;
     144 + _process.Refresh();
    141 145   
    142  - while ((DateTime.Now - startTime).TotalSeconds < 10)
    143  - {
    144  - _process.Refresh();
     146 + if (_process.HasExited)
     147 + break;
    145 148   
    146  - if (_process.HasExited)
    147  - break;
    148 149   
     150 + _appWin = _process.MainWindowHandle;
    149 151   
    150  - _appWin = _process.MainWindowHandle;
     152 + if (IntPtr.Zero != _appWin)
     153 + break;
    151 154   
    152  - if (IntPtr.Zero != _appWin)
    153  - break;
    154  - 
    155  - await Task.Delay(100);
    156  - }
     155 + await Task.Delay(100);
    157 156   }
     157 + }
    158 158   
    159  - if (_appWin != IntPtr.Zero)
    160  - {
    161  - NativeMethods.SetParent(_appWin, WindowHost.Handle);
     159 + if (_appWin != IntPtr.Zero)
     160 + {
     161 + NativeMethods.SetParent(_appWin, WindowHost.Handle);
    162 162   
    163  - // Show window before set style and resize
    164  - NativeMethods.ShowWindow(_appWin, NativeMethods.WindowShowStyle.Maximize);
     163 + // Show window before set style and resize
     164 + NativeMethods.ShowWindow(_appWin, NativeMethods.WindowShowStyle.Maximize);
    165 165   
    166  - // Remove border etc.
    167  - long style = (int)NativeMethods.GetWindowLong(_appWin, NativeMethods.GWL_STYLE);
    168  - style &= ~(NativeMethods.WS_CAPTION | NativeMethods.WS_POPUP | NativeMethods.WS_THICKFRAME);
    169  - NativeMethods.SetWindowLongPtr(_appWin, NativeMethods.GWL_STYLE, new IntPtr(style));
     166 + // Remove border etc.
     167 + long style = (int)NativeMethods.GetWindowLong(_appWin, NativeMethods.GWL_STYLE);
     168 + style &= ~(NativeMethods.WS_CAPTION | NativeMethods.WS_POPUP | NativeMethods.WS_THICKFRAME);
     169 + NativeMethods.SetWindowLongPtr(_appWin, NativeMethods.GWL_STYLE, new IntPtr(style));
    170 170   
    171  - IsConnected = true;
     171 + IsConnected = true;
    172 172   
    173  - // Resize embedded application & refresh
    174  - // Requires a short delay because it's not applied immediately
    175  - await Task.Delay(250);
    176  - ResizeEmbeddedWindow();
    177  - }
     173 + // Resize embedded application & refresh
     174 + // Requires a short delay because it's not applied immediately
     175 + await Task.Delay(250);
     176 + ResizeEmbeddedWindow();
    178 177   }
    179  - else
    180  - {
    181  - throw new Exception("Process could not be started!");
    182  - }
     178 + }
     179 + else
     180 + {
     181 + throw new Exception("Process could not be started!");
    183 182   }
    184  - catch (Exception ex)
     183 + }
     184 + catch (Exception ex)
     185 + {
     186 + if (!_closing)
    185 187   {
    186  - if (!_closing)
    187  - {
    188  - var settings = AppearanceManager.MetroDialog;
    189  - settings.AffirmativeButtonText = Localization.Resources.Strings.OK;
     188 + var settings = AppearanceManager.MetroDialog;
     189 + settings.AffirmativeButtonText = Localization.Resources.Strings.OK;
    190 190   
    191  - ConfigurationManager.Current.IsDialogOpen = true;
     191 + ConfigurationManager.Current.IsDialogOpen = true;
    192 192   
    193  - await _dialogCoordinator.ShowMessageAsync(this, Localization.Resources.Strings.Error,
    194  - ex.Message, MessageDialogStyle.Affirmative, settings);
     193 + await _dialogCoordinator.ShowMessageAsync(this, Localization.Resources.Strings.Error,
     194 + ex.Message, MessageDialogStyle.Affirmative, settings);
    195 195   
    196  - ConfigurationManager.Current.IsDialogOpen = false;
    197  - }
     196 + ConfigurationManager.Current.IsDialogOpen = false;
    198 197   }
    199  - 
    200  - IsConnecting = false;
    201 198   }
    202 199   
    203  - private void Process_Exited(object sender, EventArgs e)
    204  - {
    205  - // This happens when the user exit the process
    206  - IsConnected = false;
    207  - }
     200 + IsConnecting = false;
     201 + }
    208 202   
    209  - public void FocusEmbeddedWindow()
    210  - {
    211  - if (IsConnected)
    212  - NativeMethods.SetForegroundWindow(_process.MainWindowHandle);
    213  - }
     203 + private void Process_Exited(object sender, EventArgs e)
     204 + {
     205 + // This happens when the user exit the process
     206 + IsConnected = false;
     207 + }
     208 + 
     209 + public void FocusEmbeddedWindow()
     210 + {
     211 + if (IsConnected)
     212 + NativeMethods.SetForegroundWindow(_process.MainWindowHandle);
     213 + }
    214 214   
    215  - public void ResizeEmbeddedWindow()
    216  - {
    217  - if (IsConnected)
    218  - NativeMethods.SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, WindowHost.ClientSize.Width, WindowHost.ClientSize.Height, NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
    219  - }
     215 + public void ResizeEmbeddedWindow()
     216 + {
     217 + if (IsConnected)
     218 + NativeMethods.SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, WindowHost.ClientSize.Width, WindowHost.ClientSize.Height, NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
     219 + }
    220 220   
    221  - public void Disconnect()
    222  - {
    223  - if (IsConnected)
    224  - _process.Kill();
    225  - }
     221 + public void Disconnect()
     222 + {
     223 + if (IsConnected)
     224 + _process.Kill();
     225 + }
    226 226   
    227  - private void Reconnect()
    228  - {
    229  - if (IsConnected)
    230  - Disconnect();
     227 + private void Reconnect()
     228 + {
     229 + if (IsConnected)
     230 + Disconnect();
    231 231   
    232  - Connect();
    233  - }
     232 + Connect();
     233 + }
    234 234   
    235  - public void CloseTab()
    236  - {
    237  - _closing = true;
     235 + public void CloseTab()
     236 + {
     237 + _closing = true;
    238 238   
    239  - Disconnect();
    240  - }
    241  - #endregion
     239 + Disconnect();
     240 + }
     241 + #endregion
    242 242   
    243  - #region Events
    244  - private void WindowGrid_SizeChanged(object sender, SizeChangedEventArgs e)
    245  - {
    246  - if (IsConnected)
    247  - ResizeEmbeddedWindow();
    248  - }
    249  - #endregion
     243 + #region Events
     244 + private void WindowGrid_SizeChanged(object sender, SizeChangedEventArgs e)
     245 + {
     246 + if (IsConnected)
     247 + ResizeEmbeddedWindow();
    250 248   }
     249 + #endregion
    251 250  }
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/DragablzInterTabClient.cs
    skipped 1 lines
    2 2  using NETworkManager.Models;
    3 3  using System.Windows;
    4 4   
    5  -namespace NETworkManager.Controls
     5 +namespace NETworkManager.Controls;
     6 + 
     7 +public class DragablzInterTabClient : IInterTabClient
    6 8  {
    7  - public class DragablzInterTabClient : IInterTabClient
     9 + private readonly ApplicationName _applicationName;
     10 + 
     11 + public DragablzInterTabClient(ApplicationName applicationName)
    8 12   {
    9  - private readonly ApplicationName _applicationName;
     13 + _applicationName = applicationName;
     14 + }
    10 15   
    11  - public DragablzInterTabClient(ApplicationName applicationName)
    12  - {
    13  - _applicationName = applicationName;
    14  - }
     16 + public INewTabHost<Window> GetNewHost(IInterTabClient interTabClient, object partition, TabablzControl source)
     17 + {
     18 + var dragablzTabHostWindow = new DragablzTabHostWindow(_applicationName);
     19 + return new NewTabHost<DragablzTabHostWindow>(dragablzTabHostWindow, dragablzTabHostWindow.TabsContainer);
     20 + }
    15 21   
    16  - public INewTabHost<Window> GetNewHost(IInterTabClient interTabClient, object partition, TabablzControl source)
    17  - {
    18  - var dragablzTabHostWindow = new DragablzTabHostWindow(_applicationName);
    19  - return new NewTabHost<DragablzTabHostWindow>(dragablzTabHostWindow, dragablzTabHostWindow.TabsContainer);
    20  - }
    21  - 
    22  - public TabEmptiedResponse TabEmptiedHandler(TabablzControl tabControl, Window window)
    23  - {
    24  - return window is MainWindow ? TabEmptiedResponse.DoNothing : TabEmptiedResponse.CloseWindowOrLayoutBranch;
    25  - }
     22 + public TabEmptiedResponse TabEmptiedHandler(TabablzControl tabControl, Window window)
     23 + {
     24 + return window is MainWindow ? TabEmptiedResponse.DoNothing : TabEmptiedResponse.CloseWindowOrLayoutBranch;
    26 25   }
    27 26  }
    28 27   
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/DragablzTabHostWindow.xaml.cs
    skipped 11 lines
    12 12  using NETworkManager.Models;
    13 13  using System.Threading.Tasks;
    14 14   
    15  -namespace NETworkManager.Controls
     15 +namespace NETworkManager.Controls;
     16 + 
     17 +public partial class DragablzTabHostWindow : INotifyPropertyChanged
    16 18  {
    17  - public partial class DragablzTabHostWindow : INotifyPropertyChanged
    18  - {
    19  - #region PropertyChangedEventHandler
    20  - public event PropertyChangedEventHandler PropertyChanged;
     19 + #region PropertyChangedEventHandler
     20 + public event PropertyChangedEventHandler PropertyChanged;
    21 21   
    22  - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    23  - {
    24  - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    25  - }
    26  - #endregion
     22 + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
     23 + {
     24 + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     25 + }
     26 + #endregion
    27 27   
    28  - #region Variables
    29  - public IInterTabClient InterTabClient { get; }
    30  - private ApplicationName _applicationName;
     28 + #region Variables
     29 + public IInterTabClient InterTabClient { get; }
     30 + private ApplicationName _applicationName;
    31 31   
    32  - public ApplicationName ApplicationName
     32 + public ApplicationName ApplicationName
     33 + {
     34 + get => _applicationName;
     35 + set
    33 36   {
    34  - get => _applicationName;
    35  - set
    36  - {
    37  - if (value == _applicationName)
    38  - return;
     37 + if (value == _applicationName)
     38 + return;
    39 39   
    40  - _applicationName = value;
    41  - OnPropertyChanged();
    42  - }
     40 + _applicationName = value;
     41 + OnPropertyChanged();
    43 42   }
    44  - #endregion
     43 + }
     44 + #endregion
    45 45   
    46  - #region Constructor
    47  - public DragablzTabHostWindow(ApplicationName applicationName)
    48  - {
    49  - InitializeComponent();
    50  - DataContext = this;
     46 + #region Constructor
     47 + public DragablzTabHostWindow(ApplicationName applicationName)
     48 + {
     49 + InitializeComponent();
     50 + DataContext = this;
    51 51   
    52  - ApplicationName = applicationName;
     52 + ApplicationName = applicationName;
    53 53   
    54  - InterTabClient = new DragablzInterTabClient(applicationName);
     54 + InterTabClient = new DragablzInterTabClient(applicationName);
    55 55   
    56  - InterTabController.Partition = applicationName.ToString();
     56 + InterTabController.Partition = applicationName.ToString();
    57 57   
    58  - Title = $"NETworkManager {AssemblyManager.Current.Version} - {ApplicationNameTranslator.GetInstance().Translate(applicationName)}";
     58 + Title = $"NETworkManager {AssemblyManager.Current.Version} - {ApplicationNameTranslator.GetInstance().Translate(applicationName)}";
    59 59   
    60  - SettingsManager.Current.PropertyChanged += SettingsManager_PropertyChanged;
    61  - }
    62  - #endregion
     60 + SettingsManager.Current.PropertyChanged += SettingsManager_PropertyChanged;
     61 + }
     62 + #endregion
    63 63   
    64  - #region ICommand & Actions
    65  - public ItemActionCallback CloseItemCommand => CloseItemAction;
     64 + #region ICommand & Actions
     65 + public ItemActionCallback CloseItemCommand => CloseItemAction;
    66 66   
    67  - private void CloseItemAction(ItemActionCallbackArgs<TabablzControl> args)
     67 + private void CloseItemAction(ItemActionCallbackArgs<TabablzControl> args)
     68 + {
     69 + // Switch between application identifiert...
     70 + switch (_applicationName)
    68 71   {
    69  - // Switch between application identifiert...
    70  - switch (_applicationName)
    71  - {
    72  - case ApplicationName.None:
    73  - break;
    74  - case ApplicationName.IPScanner:
    75  - ((IPScannerView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    76  - break;
    77  - case ApplicationName.PortScanner:
    78  - ((PortScannerView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    79  - break;
    80  - case ApplicationName.Traceroute:
    81  - ((TracerouteView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    82  - break;
    83  - case ApplicationName.DNSLookup:
    84  - ((DNSLookupView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    85  - break;
    86  - case ApplicationName.RemoteDesktop:
    87  - ((RemoteDesktopControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    88  - break;
    89  - case ApplicationName.PowerShell:
    90  - ((PowerShellControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    91  - break;
    92  - case ApplicationName.PuTTY:
    93  - ((PuTTYControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    94  - break;
    95  - case ApplicationName.AWSSessionManager:
    96  - ((AWSSessionManagerControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    97  - break;
    98  - case ApplicationName.TigerVNC:
    99  - ((TigerVNCControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    100  - break;
    101  - case ApplicationName.WebConsole:
    102  - ((WebConsoleControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    103  - break;
    104  - case ApplicationName.SNMP:
    105  - ((SNMPView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    106  - break;
    107  - case ApplicationName.SNTPLookup:
    108  - ((SNTPLookupView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    109  - break;
    110  - case ApplicationName.Whois:
    111  - ((WhoisView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
    112  - break;
    113  - default:
    114  - throw new ArgumentOutOfRangeException();
    115  - }
     72 + case ApplicationName.None:
     73 + break;
     74 + case ApplicationName.IPScanner:
     75 + ((IPScannerView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     76 + break;
     77 + case ApplicationName.PortScanner:
     78 + ((PortScannerView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     79 + break;
     80 + case ApplicationName.Traceroute:
     81 + ((TracerouteView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     82 + break;
     83 + case ApplicationName.DNSLookup:
     84 + ((DNSLookupView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     85 + break;
     86 + case ApplicationName.RemoteDesktop:
     87 + ((RemoteDesktopControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     88 + break;
     89 + case ApplicationName.PowerShell:
     90 + ((PowerShellControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     91 + break;
     92 + case ApplicationName.PuTTY:
     93 + ((PuTTYControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     94 + break;
     95 + case ApplicationName.AWSSessionManager:
     96 + ((AWSSessionManagerControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     97 + break;
     98 + case ApplicationName.TigerVNC:
     99 + ((TigerVNCControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     100 + break;
     101 + case ApplicationName.WebConsole:
     102 + ((WebConsoleControl)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     103 + break;
     104 + case ApplicationName.SNMP:
     105 + ((SNMPView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     106 + break;
     107 + case ApplicationName.SNTPLookup:
     108 + ((SNTPLookupView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     109 + break;
     110 + case ApplicationName.Whois:
     111 + ((WhoisView)((DragablzTabItem)args.DragablzItem.Content).View).CloseTab();
     112 + break;
     113 + default:
     114 + throw new ArgumentOutOfRangeException();
    116 115   }
     116 + }
    117 117   
    118  - #region RemoteDesktop Commands
    119  - private bool RemoteDesktop_Disconnected_CanExecute(object view)
    120  - {
    121  - if (view is RemoteDesktopControl control)
    122  - return !control.IsConnected;
     118 + #region RemoteDesktop Commands
     119 + private bool RemoteDesktop_Disconnected_CanExecute(object view)
     120 + {
     121 + if (view is RemoteDesktopControl control)
     122 + return !control.IsConnected;
    123 123   
    124  - return false;
    125  - }
     124 + return false;
     125 + }
    126 126   
    127  - private bool RemoteDesktop_Connected_CanExecute(object view)
    128  - {
    129  - if (view is RemoteDesktopControl control)
    130  - return control.IsConnected;
     127 + private bool RemoteDesktop_Connected_CanExecute(object view)
     128 + {
     129 + if (view is RemoteDesktopControl control)
     130 + return control.IsConnected;
    131 131   
    132  - return false;
    133  - }
     132 + return false;
     133 + }
    134 134   
    135  - public ICommand RemoteDesktop_ReconnectCommand => new RelayCommand(RemoteDesktop_ReconnectAction, RemoteDesktop_Disconnected_CanExecute);
     135 + public ICommand RemoteDesktop_ReconnectCommand => new RelayCommand(RemoteDesktop_ReconnectAction, RemoteDesktop_Disconnected_CanExecute);
    136 136   
    137  - private void RemoteDesktop_ReconnectAction(object view)
     137 + private void RemoteDesktop_ReconnectAction(object view)
     138 + {
     139 + if (view is RemoteDesktopControl control)
    138 140   {
    139  - if (view is RemoteDesktopControl control)
    140  - {
    141  - if (control.ReconnectCommand.CanExecute(null))
    142  - control.ReconnectCommand.Execute(null);
    143  - }
     141 + if (control.ReconnectCommand.CanExecute(null))
     142 + control.ReconnectCommand.Execute(null);
    144 143   }
     144 + }
    145 145   
    146  - public ICommand RemoteDesktop_DisconnectCommand => new RelayCommand(RemoteDesktop_DisconnectAction, RemoteDesktop_Connected_CanExecute);
     146 + public ICommand RemoteDesktop_DisconnectCommand => new RelayCommand(RemoteDesktop_DisconnectAction, RemoteDesktop_Connected_CanExecute);
    147 147   
    148  - private void RemoteDesktop_DisconnectAction(object view)
     148 + private void RemoteDesktop_DisconnectAction(object view)
     149 + {
     150 + if (view is RemoteDesktopControl control)
    149 151   {
    150  - if (view is RemoteDesktopControl control)
    151  - {
    152  - if (control.DisconnectCommand.CanExecute(null))
    153  - control.DisconnectCommand.Execute(null);
    154  - }
     152 + if (control.DisconnectCommand.CanExecute(null))
     153 + control.DisconnectCommand.Execute(null);
    155 154   }
     155 + }
    156 156   
    157  - public ICommand RemoteDesktop_FullscreenCommand => new RelayCommand(RemoteDesktop_FullscreenAction, RemoteDesktop_Connected_CanExecute);
     157 + public ICommand RemoteDesktop_FullscreenCommand => new RelayCommand(RemoteDesktop_FullscreenAction, RemoteDesktop_Connected_CanExecute);
    158 158   
    159  - private void RemoteDesktop_FullscreenAction(object view)
    160  - {
    161  - if (view is RemoteDesktopControl control)
    162  - control.FullScreen();
    163  - }
     159 + private void RemoteDesktop_FullscreenAction(object view)
     160 + {
     161 + if (view is RemoteDesktopControl control)
     162 + control.FullScreen();
     163 + }
    164 164   
    165  - public ICommand RemoteDesktop_AdjustScreenCommand => new RelayCommand(RemoteDesktop_AdjustScreenAction, RemoteDesktop_Connected_CanExecute);
     165 + public ICommand RemoteDesktop_AdjustScreenCommand => new RelayCommand(RemoteDesktop_AdjustScreenAction, RemoteDesktop_Connected_CanExecute);
    166 166   
    167  - private void RemoteDesktop_AdjustScreenAction(object view)
    168  - {
    169  - if (view is RemoteDesktopControl control)
    170  - control.AdjustScreen();
    171  - }
     167 + private void RemoteDesktop_AdjustScreenAction(object view)
     168 + {
     169 + if (view is RemoteDesktopControl control)
     170 + control.AdjustScreen();
     171 + }
    172 172   
    173  - public ICommand RemoteDesktop_SendCtrlAltDelCommand => new RelayCommand(RemoteDesktop_SendCtrlAltDelAction, RemoteDesktop_Connected_CanExecute);
     173 + public ICommand RemoteDesktop_SendCtrlAltDelCommand => new RelayCommand(RemoteDesktop_SendCtrlAltDelAction, RemoteDesktop_Connected_CanExecute);
    174 174   
    175  - private async void RemoteDesktop_SendCtrlAltDelAction(object view)
     175 + private async void RemoteDesktop_SendCtrlAltDelAction(object view)
     176 + {
     177 + if (view is RemoteDesktopControl control)
    176 178   {
    177  - if (view is RemoteDesktopControl control)
     179 + try
    178 180   {
    179  - try
    180  - {
    181  - control.SendKey(Keystroke.CtrlAltDel);
    182  - }
    183  - catch (Exception ex)
    184  - {
    185  - ConfigurationManager.Current.IsDialogOpen = true;
     181 + control.SendKey(Keystroke.CtrlAltDel);
     182 + }
     183 + catch (Exception ex)
     184 + {
     185 + ConfigurationManager.Current.IsDialogOpen = true;
    186 186   
    187  - await this.ShowMessageAsync(Localization.Resources.Strings.Error, string.Format("{0}\n\nMessage:\n{1}", NETworkManager.Localization.Resources.Strings.CouldNotSendKeystroke, ex.Message, MessageDialogStyle.Affirmative, AppearanceManager.MetroDialog));
     187 + await this.ShowMessageAsync(Localization.Resources.Strings.Error, string.Format("{0}\n\nMessage:\n{1}", NETworkManager.Localization.Resources.Strings.CouldNotSendKeystroke, ex.Message, MessageDialogStyle.Affirmative, AppearanceManager.MetroDialog));
    188 188   
    189  - ConfigurationManager.Current.IsDialogOpen = false;
    190  - }
     189 + ConfigurationManager.Current.IsDialogOpen = false;
    191 190   }
    192 191   }
    193  - #endregion
     192 + }
     193 + #endregion
    194 194   
    195  - #region PowerShell Commands
    196  - private bool PowerShell_Disconnected_CanExecute(object view)
    197  - {
    198  - if (view is PowerShellControl control)
    199  - return !control.IsConnected;
     195 + #region PowerShell Commands
     196 + private bool PowerShell_Disconnected_CanExecute(object view)
     197 + {
     198 + if (view is PowerShellControl control)
     199 + return !control.IsConnected;
    200 200   
    201  - return false;
    202  - }
     201 + return false;
     202 + }
    203 203   
    204  - public ICommand PowerShell_ReconnectCommand => new RelayCommand(PowerShell_ReconnectAction);
     204 + public ICommand PowerShell_ReconnectCommand => new RelayCommand(PowerShell_ReconnectAction);
    205 205   
    206  - private void PowerShell_ReconnectAction(object view)
     206 + private void PowerShell_ReconnectAction(object view)
     207 + {
     208 + if (view is PowerShellControl control)
    207 209   {
    208  - if (view is PowerShellControl control)
    209  - {
    210  - if (control.ReconnectCommand.CanExecute(null))
    211  - control.ReconnectCommand.Execute(null);
    212  - }
     210 + if (control.ReconnectCommand.CanExecute(null))
     211 + control.ReconnectCommand.Execute(null);
    213 212   }
     213 + }
    214 214   
    215  - public ICommand PowerShell_ResizeWindowCommand => new RelayCommand(PowerShell_ResizeWindowAction, PowerShell_Disconnected_CanExecute);
     215 + public ICommand PowerShell_ResizeWindowCommand => new RelayCommand(PowerShell_ResizeWindowAction, PowerShell_Disconnected_CanExecute);
    216 216   
    217  - private void PowerShell_ResizeWindowAction(object view)
    218  - {
    219  - if (view is PowerShellControl control)
    220  - control.ResizeEmbeddedWindow();
    221  - }
    222  - #endregion
     217 + private void PowerShell_ResizeWindowAction(object view)
     218 + {
     219 + if (view is PowerShellControl control)
     220 + control.ResizeEmbeddedWindow();
     221 + }
     222 + #endregion
    223 223   
    224  - #region PuTTY Commands
    225  - private bool PuTTY_Connected_CanExecute(object view)
    226  - {
    227  - if (view is PuTTYControl control)
    228  - return control.IsConnected;
     224 + #region PuTTY Commands
     225 + private bool PuTTY_Connected_CanExecute(object view)
     226 + {
     227 + if (view is PuTTYControl control)
     228 + return control.IsConnected;
    229 229   
    230  - return false;
    231  - }
     230 + return false;
     231 + }
    232 232   
    233  - public ICommand PuTTY_ReconnectCommand => new RelayCommand(PuTTY_ReconnectAction);
     233 + public ICommand PuTTY_ReconnectCommand => new RelayCommand(PuTTY_ReconnectAction);
    234 234   
    235  - private void PuTTY_ReconnectAction(object view)
     235 + private void PuTTY_ReconnectAction(object view)
     236 + {
     237 + if (view is PuTTYControl control)
    236 238   {
    237  - if (view is PuTTYControl control)
    238  - {
    239  - if (control.ReconnectCommand.CanExecute(null))
    240  - control.ReconnectCommand.Execute(null);
    241  - }
     239 + if (control.ReconnectCommand.CanExecute(null))
     240 + control.ReconnectCommand.Execute(null);
    242 241   }
     242 + }
    243 243   
    244  - public ICommand PuTTY_ResizeWindowCommand => new RelayCommand(PuTTY_ResizeWindowAction, PuTTY_Connected_CanExecute);
     244 + public ICommand PuTTY_ResizeWindowCommand => new RelayCommand(PuTTY_ResizeWindowAction, PuTTY_Connected_CanExecute);
    245 245   
    246  - private void PuTTY_ResizeWindowAction(object view)
    247  - {
    248  - if (view is PuTTYControl control)
    249  - control.ResizeEmbeddedWindow();
    250  - }
     246 + private void PuTTY_ResizeWindowAction(object view)
     247 + {
     248 + if (view is PuTTYControl control)
     249 + control.ResizeEmbeddedWindow();
     250 + }
    251 251   
    252  - public ICommand PuTTY_RestartSessionCommand => new RelayCommand(PuTTY_RestartSessionAction, PuTTY_Connected_CanExecute);
     252 + public ICommand PuTTY_RestartSessionCommand => new RelayCommand(PuTTY_RestartSessionAction, PuTTY_Connected_CanExecute);
    253 253   
    254  - private void PuTTY_RestartSessionAction(object view)
    255  - {
    256  - if (view is PuTTYControl control)
    257  - control.RestartSession();
    258  - }
    259  - #endregion
     254 + private void PuTTY_RestartSessionAction(object view)
     255 + {
     256 + if (view is PuTTYControl control)
     257 + control.RestartSession();
     258 + }
     259 + #endregion
    260 260   
    261  - #region AWSSessionManager Commands
    262  - private bool AWSSessionManager_Disconnected_CanExecute(object view)
    263  - {
    264  - if (view is AWSSessionManagerControl control)
    265  - return !control.IsConnected;
     261 + #region AWSSessionManager Commands
     262 + private bool AWSSessionManager_Disconnected_CanExecute(object view)
     263 + {
     264 + if (view is AWSSessionManagerControl control)
     265 + return !control.IsConnected;
    266 266   
    267  - return false;
    268  - }
     267 + return false;
     268 + }
    269 269   
    270  - public ICommand AWSSessionManager_ReconnectCommand => new RelayCommand(AWSSessionManager_ReconnectAction);
     270 + public ICommand AWSSessionManager_ReconnectCommand => new RelayCommand(AWSSessionManager_ReconnectAction);
    271 271   
    272  - private void AWSSessionManager_ReconnectAction(object view)
     272 + private void AWSSessionManager_ReconnectAction(object view)
     273 + {
     274 + if (view is AWSSessionManagerControl control)
    273 275   {
    274  - if (view is AWSSessionManagerControl control)
    275  - {
    276  - if (control.ReconnectCommand.CanExecute(null))
    277  - control.ReconnectCommand.Execute(null);
    278  - }
     276 + if (control.ReconnectCommand.CanExecute(null))
     277 + control.ReconnectCommand.Execute(null);
    279 278   }
     279 + }
    280 280   
    281  - public ICommand AWSSessionManager_ResizeWindowCommand => new RelayCommand(AWSSessionManager_ResizeWindowAction, AWSSessionManager_Disconnected_CanExecute);
     281 + public ICommand AWSSessionManager_ResizeWindowCommand => new RelayCommand(AWSSessionManager_ResizeWindowAction, AWSSessionManager_Disconnected_CanExecute);
    282 282   
    283  - private void AWSSessionManager_ResizeWindowAction(object view)
    284  - {
    285  - if (view is PowerShellControl control)
    286  - control.ResizeEmbeddedWindow();
    287  - }
    288  - #endregion
     283 + private void AWSSessionManager_ResizeWindowAction(object view)
     284 + {
     285 + if (view is PowerShellControl control)
     286 + control.ResizeEmbeddedWindow();
     287 + }
     288 + #endregion
    289 289   
    290  - #region TigerVNC Commands
    291  - public ICommand TigerVNC_ReconnectCommand => new RelayCommand(TigerVNC_ReconnectAction);
     290 + #region TigerVNC Commands
     291 + public ICommand TigerVNC_ReconnectCommand => new RelayCommand(TigerVNC_ReconnectAction);
    292 292   
    293  - private void TigerVNC_ReconnectAction(object view)
     293 + private void TigerVNC_ReconnectAction(object view)
     294 + {
     295 + if (view is TigerVNCControl control)
    294 296   {
    295  - if (view is TigerVNCControl control)
    296  - {
    297  - if (control.ReconnectCommand.CanExecute(null))
    298  - control.ReconnectCommand.Execute(null);
    299  - }
     297 + if (control.ReconnectCommand.CanExecute(null))
     298 + control.ReconnectCommand.Execute(null);
    300 299   }
    301  - #endregion
     300 + }
     301 + #endregion
    302 302   
    303  - #region WebConsole Commands
    304  - public ICommand WebConsole_ReloadCommand => new RelayCommand(WebConsole_RefreshAction);
     303 + #region WebConsole Commands
     304 + public ICommand WebConsole_ReloadCommand => new RelayCommand(WebConsole_RefreshAction);
    305 305   
    306  - private void WebConsole_RefreshAction(object view)
     306 + private void WebConsole_RefreshAction(object view)
     307 + {
     308 + if (view is WebConsoleControl control)
    307 309   {
    308  - if (view is WebConsoleControl control)
    309  - {
    310  - if (control.ReloadCommand.CanExecute(null))
    311  - control.ReloadCommand.Execute(null);
    312  - }
     310 + if (control.ReloadCommand.CanExecute(null))
     311 + control.ReloadCommand.Execute(null);
    313 312   }
    314  - #endregion
    315  - #endregion
     313 + }
     314 + #endregion
     315 + #endregion
    316 316   
    317  - private async void FocusEmbeddedWindow()
     317 + private async void FocusEmbeddedWindow()
     318 + {
     319 + // Delay the focus to prevent blocking the ui
     320 + do
    318 321   {
    319  - // Delay the focus to prevent blocking the ui
    320  - do
    321  - {
    322  - await Task.Delay(250);
    323  - } while (Mouse.LeftButton == MouseButtonState.Pressed);
     322 + await Task.Delay(250);
     323 + } while (Mouse.LeftButton == MouseButtonState.Pressed);
    324 324   
    325  - // Switch by name
    326  - switch (ApplicationName)
    327  - {
    328  - case ApplicationName.PowerShell:
    329  - ((PowerShellControl)((DragablzTabItem)TabsContainer?.SelectedItem)?.View)?.FocusEmbeddedWindow();
    330  - break;
    331  - case ApplicationName.PuTTY:
    332  - ((PuTTYControl)((DragablzTabItem)TabsContainer?.SelectedItem)?.View)?.FocusEmbeddedWindow();
    333  - break;
    334  - case ApplicationName.AWSSessionManager:
    335  - ((AWSSessionManagerControl)((DragablzTabItem)TabsContainer?.SelectedItem)?.View)?.FocusEmbeddedWindow();
    336  - break;
    337  - }
     325 + // Switch by name
     326 + switch (ApplicationName)
     327 + {
     328 + case ApplicationName.PowerShell:
     329 + ((PowerShellControl)((DragablzTabItem)TabsContainer?.SelectedItem)?.View)?.FocusEmbeddedWindow();
     330 + break;
     331 + case ApplicationName.PuTTY:
     332 + ((PuTTYControl)((DragablzTabItem)TabsContainer?.SelectedItem)?.View)?.FocusEmbeddedWindow();
     333 + break;
     334 + case ApplicationName.AWSSessionManager:
     335 + ((AWSSessionManagerControl)((DragablzTabItem)TabsContainer?.SelectedItem)?.View)?.FocusEmbeddedWindow();
     336 + break;
    338 337   }
     338 + }
    339 339   
    340  - #region Events
    341  - private void SettingsManager_PropertyChanged(object sender, PropertyChangedEventArgs e)
    342  - {
     340 + #region Events
     341 + private void SettingsManager_PropertyChanged(object sender, PropertyChangedEventArgs e)
     342 + {
    343 343   
    344  - }
     344 + }
    345 345   
    346  - private void MetroWindow_Activated(object sender, EventArgs e)
    347  - {
    348  - FocusEmbeddedWindow();
    349  - }
    350  - #endregion
     346 + private void MetroWindow_Activated(object sender, EventArgs e)
     347 + {
     348 + FocusEmbeddedWindow();
    351 349   }
     350 + #endregion
    352 351  }
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/DragablzTabItem.cs
    1 1  using NETworkManager.ViewModels;
    2 2  using System.Windows.Controls;
    3 3   
    4  -namespace NETworkManager.Controls
     4 +namespace NETworkManager.Controls;
     5 + 
     6 +public class DragablzTabItem : ViewModelBase
    5 7  {
    6  - public class DragablzTabItem : ViewModelBase
     8 + private string _header;
     9 + public string Header
    7 10   {
    8  - private string _header;
    9  - public string Header
     11 + get => _header;
     12 + set
    10 13   {
    11  - get => _header;
    12  - set
    13  - {
    14  - if (value == _header)
    15  - return;
     14 + if (value == _header)
     15 + return;
    16 16   
    17  - _header = value;
    18  - OnPropertyChanged();
    19  - }
     17 + _header = value;
     18 + OnPropertyChanged();
    20 19   }
     20 + }
    21 21   
    22  - public UserControl View { get; set; }
    23  - public int Id { get; set; }
     22 + public UserControl View { get; set; }
     23 + public int Id { get; set; }
    24 24   
    25  - public DragablzTabItem(string header, UserControl view)
    26  - {
    27  - Header = header;
    28  - View = view;
    29  - }
     25 + public DragablzTabItem(string header, UserControl view)
     26 + {
     27 + Header = header;
     28 + View = view;
     29 + }
    30 30   
    31  - public DragablzTabItem(string header, UserControl view, int id)
    32  - {
    33  - Header = header;
    34  - View = view;
    35  - Id = id;
    36  - }
     31 + public DragablzTabItem(string header, UserControl view, int id)
     32 + {
     33 + Header = header;
     34 + View = view;
     35 + Id = id;
    37 36   }
    38 37  }
    39 38   
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/LvlChartsBandwidthTooltip.xaml.cs
    skipped 3 lines
    4 4  using System.Runtime.CompilerServices;
    5 5   
    6 6   
    7  -namespace NETworkManager.Controls
     7 +namespace NETworkManager.Controls;
     8 + 
     9 +public partial class LvlChartsBandwidthTooltip : IChartTooltip
    8 10  {
    9  - public partial class LvlChartsBandwidthTooltip : IChartTooltip
    10  - {
    11  - public event PropertyChangedEventHandler PropertyChanged;
     11 + public event PropertyChangedEventHandler PropertyChanged;
    12 12   
    13  - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    14  - {
    15  - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    16  - }
     13 + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
     14 + {
     15 + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     16 + }
    17 17  
    18  - private TooltipData _data;
     18 + private TooltipData _data;
    19 19   
    20  - public TooltipData Data
     20 + public TooltipData Data
     21 + {
     22 + get { return _data; }
     23 + set
    21 24   {
    22  - get { return _data; }
    23  - set
    24  - {
    25  - _data = value;
    26  - OnPropertyChanged();
    27  - }
     25 + _data = value;
     26 + OnPropertyChanged();
    28 27   }
     28 + }
    29 29   
    30  - public TooltipSelectionMode? SelectionMode { get; set; }
     30 + public TooltipSelectionMode? SelectionMode { get; set; }
    31 31  
    32  - public LvlChartsBandwidthTooltip()
    33  - {
    34  - InitializeComponent();
     32 + public LvlChartsBandwidthTooltip()
     33 + {
     34 + InitializeComponent();
    35 35  
    36  - DataContext = this;
    37  - }
     36 + DataContext = this;
    38 37   }
    39 38  }
    40 39   
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/LvlChartsPingTimeTooltip.xaml.cs
    skipped 3 lines
    4 4  using System.Runtime.CompilerServices;
    5 5   
    6 6   
    7  -namespace NETworkManager.Controls
     7 +namespace NETworkManager.Controls;
     8 + 
     9 +public partial class LvlChartsPingTimeTooltip : IChartTooltip
    8 10  {
    9  - public partial class LvlChartsPingTimeTooltip : IChartTooltip
    10  - {
    11  - public event PropertyChangedEventHandler PropertyChanged;
     11 + public event PropertyChangedEventHandler PropertyChanged;
    12 12   
    13  - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    14  - {
    15  - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    16  - }
     13 + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
     14 + {
     15 + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     16 + }
    17 17  
    18  - private TooltipData _data;
     18 + private TooltipData _data;
    19 19   
    20  - public TooltipData Data
     20 + public TooltipData Data
     21 + {
     22 + get { return _data; }
     23 + set
    21 24   {
    22  - get { return _data; }
    23  - set
    24  - {
    25  - _data = value;
    26  - OnPropertyChanged();
    27  - }
     25 + _data = value;
     26 + OnPropertyChanged();
    28 27   }
     28 + }
    29 29   
    30  - public TooltipSelectionMode? SelectionMode { get; set; }
     30 + public TooltipSelectionMode? SelectionMode { get; set; }
    31 31  
    32  - public LvlChartsPingTimeTooltip()
    33  - {
    34  - InitializeComponent();
     32 + public LvlChartsPingTimeTooltip()
     33 + {
     34 + InitializeComponent();
    35 35  
    36  - DataContext = this;
    37  - }
     36 + DataContext = this;
    38 37   }
    39 38  }
    40 39   
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/LvlChartsWiFiChannelTooltip.xaml.cs
    skipped 3 lines
    4 4  using System.Runtime.CompilerServices;
    5 5   
    6 6   
    7  -namespace NETworkManager.Controls
     7 +namespace NETworkManager.Controls;
     8 + 
     9 +public partial class LvlChartsWiFiChannelTooltip : IChartTooltip
    8 10  {
    9  - public partial class LvlChartsWiFiChannelTooltip : IChartTooltip
    10  - {
    11  - public event PropertyChangedEventHandler PropertyChanged;
     11 + public event PropertyChangedEventHandler PropertyChanged;
    12 12   
    13  - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    14  - {
    15  - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    16  - }
     13 + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
     14 + {
     15 + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     16 + }
    17 17  
    18  - private TooltipData _data;
     18 + private TooltipData _data;
    19 19   
    20  - public TooltipData Data
     20 + public TooltipData Data
     21 + {
     22 + get { return _data; }
     23 + set
    21 24   {
    22  - get { return _data; }
    23  - set
    24  - {
    25  - _data = value;
    26  - OnPropertyChanged();
    27  - }
     25 + _data = value;
     26 + OnPropertyChanged();
    28 27   }
     28 + }
    29 29   
    30  - public TooltipSelectionMode? SelectionMode { get; set; }
     30 + public TooltipSelectionMode? SelectionMode { get; set; }
    31 31  
    32  - public LvlChartsWiFiChannelTooltip()
    33  - {
    34  - InitializeComponent();
     32 + public LvlChartsWiFiChannelTooltip()
     33 + {
     34 + InitializeComponent();
    35 35   
    36  - DataContext = this;
    37  - }
     36 + DataContext = this;
    38 37   }
    39 38  }
    40 39   
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/PowerShellControl.xaml.cs
    skipped 12 lines
    13 13  using NETworkManager.Settings;
    14 14  using NETworkManager.Models.PowerShell;
    15 15   
    16  -namespace NETworkManager.Controls
     16 +namespace NETworkManager.Controls;
     17 + 
     18 +public partial class PowerShellControl : INotifyPropertyChanged
    17 19  {
    18  - public partial class PowerShellControl : INotifyPropertyChanged
     20 + #region PropertyChangedEventHandler
     21 + public event PropertyChangedEventHandler PropertyChanged;
     22 + 
     23 + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    19 24   {
    20  - #region PropertyChangedEventHandler
    21  - public event PropertyChangedEventHandler PropertyChanged;
     25 + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     26 + }
     27 + #endregion
    22 28   
    23  - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    24  - {
    25  - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    26  - }
    27  - #endregion
     29 + #region Variables
     30 + private bool _initialized;
     31 + private bool _closing; // When the tab is closed --> OnClose()
    28 32   
    29  - #region Variables
    30  - private bool _initialized;
    31  - private bool _closing; // When the tab is closed --> OnClose()
     33 + private readonly IDialogCoordinator _dialogCoordinator;
    32 34   
    33  - private readonly IDialogCoordinator _dialogCoordinator;
     35 + private readonly PowerShellSessionInfo _sessionInfo;
    34 36   
    35  - private readonly PowerShellSessionInfo _sessionInfo;
     37 + private Process _process;
     38 + private IntPtr _appWin;
    36 39   
    37  - private Process _process;
    38  - private IntPtr _appWin;
    39  - 
    40  - private bool _isConnected;
    41  - public bool IsConnected
     40 + private bool _isConnected;
     41 + public bool IsConnected
     42 + {
     43 + get => _isConnected;
     44 + set
    42 45   {
    43  - get => _isConnected;
    44  - set
    45  - {
    46  - if (value == _isConnected)
    47  - return;
     46 + if (value == _isConnected)
     47 + return;
    48 48   
    49  - _isConnected = value;
    50  - OnPropertyChanged();
    51  - }
     49 + _isConnected = value;
     50 + OnPropertyChanged();
    52 51   }
     52 + }
    53 53   
    54  - private bool _isConnecting;
    55  - public bool IsConnecting
     54 + private bool _isConnecting;
     55 + public bool IsConnecting
     56 + {
     57 + get => _isConnecting;
     58 + set
    56 59   {
    57  - get => _isConnecting;
    58  - set
    59  - {
    60  - if (value == _isConnecting)
    61  - return;
     60 + if (value == _isConnecting)
     61 + return;
    62 62   
    63  - _isConnecting = value;
    64  - OnPropertyChanged();
    65  - }
     63 + _isConnecting = value;
     64 + OnPropertyChanged();
    66 65   }
    67  - #endregion
     66 + }
     67 + #endregion
    68 68   
    69  - #region Constructor, load
    70  - public PowerShellControl(PowerShellSessionInfo info)
    71  - {
    72  - InitializeComponent();
    73  - DataContext = this;
     69 + #region Constructor, load
     70 + public PowerShellControl(PowerShellSessionInfo info)
     71 + {
     72 + InitializeComponent();
     73 + DataContext = this;
    74 74   
    75  - _dialogCoordinator = DialogCoordinator.Instance;
     75 + _dialogCoordinator = DialogCoordinator.Instance;
    76 76   
    77  - _sessionInfo = info;
     77 + _sessionInfo = info;
    78 78   
    79  - Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
    80  - }
     79 + Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
     80 + }
    81 81   
    82  - private void UserControl_Loaded(object sender, RoutedEventArgs e)
    83  - {
    84  - // Connect after the control is drawn and only on the first init
    85  - if (_initialized)
    86  - return;
     82 + private void UserControl_Loaded(object sender, RoutedEventArgs e)
     83 + {
     84 + // Connect after the control is drawn and only on the first init
     85 + if (_initialized)
     86 + return;
    87 87   
    88  - // Fix: The control is not visible by default, thus height and width is not set. If the values are not set, the size does not scale properly
    89  - WindowHost.Height = (int)ActualHeight;
    90  - WindowHost.Width = (int)ActualWidth;
     88 + // Fix: The control is not visible by default, thus height and width is not set. If the values are not set, the size does not scale properly
     89 + WindowHost.Height = (int)ActualHeight;
     90 + WindowHost.Width = (int)ActualWidth;
    91 91   
    92  - Connect();
    93  - _initialized = true;
    94  - }
     92 + Connect();
     93 + _initialized = true;
     94 + }
    95 95   
    96  - private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
    97  - {
    98  - CloseTab();
    99  - }
    100  - #endregion
     96 + private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
     97 + {
     98 + CloseTab();
     99 + }
     100 + #endregion
    101 101   
    102  - #region ICommands & Actions
    103  - public ICommand ReconnectCommand
    104  - {
    105  - get { return new RelayCommand(p => ReconnectAction()); }
    106  - }
     102 + #region ICommands & Actions
     103 + public ICommand ReconnectCommand
     104 + {
     105 + get { return new RelayCommand(p => ReconnectAction()); }
     106 + }
    107 107   
    108  - private void ReconnectAction()
     108 + private void ReconnectAction()
     109 + {
     110 + Reconnect();
     111 + }
     112 + #endregion
     113 + 
     114 + #region Methods
     115 + private async Task Connect()
     116 + {
     117 + IsConnecting = true;
     118 + 
     119 + var info = new ProcessStartInfo
    109 120   {
    110  - Reconnect();
    111  - }
    112  - #endregion
     121 + FileName = _sessionInfo.ApplicationFilePath,
     122 + Arguments = PowerShell.BuildCommandLine(_sessionInfo)
     123 + };
    113 124   
    114  - #region Methods
    115  - private async Task Connect()
     125 + try
    116 126   {
    117  - IsConnecting = true;
     127 + _process = Process.Start(info);
    118 128   
    119  - var info = new ProcessStartInfo
     129 + if (_process != null)
    120 130   {
    121  - FileName = _sessionInfo.ApplicationFilePath,
    122  - Arguments = PowerShell.BuildCommandLine(_sessionInfo)
    123  - };
     131 + _process.EnableRaisingEvents = true;
     132 + _process.Exited += Process_Exited;
    124 133   
    125  - try
    126  - {
    127  - _process = Process.Start(info);
     134 + // Embed window into panel, remove border etc.
     135 + // _process.WaitForInputIdle();
     136 + _appWin = _process.MainWindowHandle;
    128 137   
    129  - if (_process != null)
     138 + if (_appWin == IntPtr.Zero)
    130 139   {
    131  - _process.EnableRaisingEvents = true;
    132  - _process.Exited += Process_Exited;
     140 + var startTime = DateTime.Now;
    133 141   
    134  - // Embed window into panel, remove border etc.
    135  - // _process.WaitForInputIdle();
    136  - _appWin = _process.MainWindowHandle;
    137  - 
    138  - if (_appWin == IntPtr.Zero)
     142 + while ((DateTime.Now - startTime).TotalSeconds < 10)
    139 143   {
    140  - var startTime = DateTime.Now;
     144 + _process.Refresh();
    141 145   
    142  - while ((DateTime.Now - startTime).TotalSeconds < 10)
    143  - {
    144  - _process.Refresh();
     146 + if (_process.HasExited)
     147 + break;
    145 148  
    146  - if (_process.HasExited)
    147  - break;
    148 149   
     150 + _appWin = _process.MainWindowHandle;
    149 151   
    150  - _appWin = _process.MainWindowHandle;
     152 + if (IntPtr.Zero != _appWin)
     153 + break;
    151 154   
    152  - if (IntPtr.Zero != _appWin)
    153  - break;
    154  - 
    155  - await Task.Delay(100);
    156  - }
     155 + await Task.Delay(100);
    157 156   }
     157 + }
    158 158   
    159  - if (_appWin != IntPtr.Zero)
    160  - {
    161  - NativeMethods.SetParent(_appWin, WindowHost.Handle);
     159 + if (_appWin != IntPtr.Zero)
     160 + {
     161 + NativeMethods.SetParent(_appWin, WindowHost.Handle);
    162 162   
    163  - // Show window before set style and resize
    164  - NativeMethods.ShowWindow(_appWin, NativeMethods.WindowShowStyle.Maximize);
     163 + // Show window before set style and resize
     164 + NativeMethods.ShowWindow(_appWin, NativeMethods.WindowShowStyle.Maximize);
    165 165   
    166  - // Remove border etc.
    167  - long style = (int)NativeMethods.GetWindowLong(_appWin, NativeMethods.GWL_STYLE);
    168  - style &= ~(NativeMethods.WS_CAPTION | NativeMethods.WS_POPUP | NativeMethods.WS_THICKFRAME);
    169  - NativeMethods.SetWindowLongPtr(_appWin, NativeMethods.GWL_STYLE, new IntPtr(style));
     166 + // Remove border etc.
     167 + long style = (int)NativeMethods.GetWindowLong(_appWin, NativeMethods.GWL_STYLE);
     168 + style &= ~(NativeMethods.WS_CAPTION | NativeMethods.WS_POPUP | NativeMethods.WS_THICKFRAME);
     169 + NativeMethods.SetWindowLongPtr(_appWin, NativeMethods.GWL_STYLE, new IntPtr(style));
    170 170  
    171  - IsConnected = true;
     171 + IsConnected = true;
    172 172   
    173  - // Resize embedded application & refresh
    174  - // Requires a short delay because it's not applied immediately
    175  - await Task.Delay(250);
    176  - ResizeEmbeddedWindow();
    177  - }
     173 + // Resize embedded application & refresh
     174 + // Requires a short delay because it's not applied immediately
     175 + await Task.Delay(250);
     176 + ResizeEmbeddedWindow();
    178 177   }
    179  - else
    180  - {
    181  - throw new Exception("Process could not be started!");
    182  - }
     178 + }
     179 + else
     180 + {
     181 + throw new Exception("Process could not be started!");
    183 182   }
    184  - catch (Exception ex)
     183 + }
     184 + catch (Exception ex)
     185 + {
     186 + if (!_closing)
    185 187   {
    186  - if (!_closing)
    187  - {
    188  - var settings = AppearanceManager.MetroDialog;
    189  - settings.AffirmativeButtonText = Localization.Resources.Strings.OK;
     188 + var settings = AppearanceManager.MetroDialog;
     189 + settings.AffirmativeButtonText = Localization.Resources.Strings.OK;
    190 190   
    191  - ConfigurationManager.Current.IsDialogOpen = true;
     191 + ConfigurationManager.Current.IsDialogOpen = true;
    192 192   
    193  - await _dialogCoordinator.ShowMessageAsync(this, Localization.Resources.Strings.Error,
    194  - ex.Message, MessageDialogStyle.Affirmative, settings);
     193 + await _dialogCoordinator.ShowMessageAsync(this, Localization.Resources.Strings.Error,
     194 + ex.Message, MessageDialogStyle.Affirmative, settings);
    195 195   
    196  - ConfigurationManager.Current.IsDialogOpen = false;
    197  - }
     196 + ConfigurationManager.Current.IsDialogOpen = false;
    198 197   }
    199  - 
    200  - IsConnecting = false;
    201 198   }
    202 199   
    203  - private void Process_Exited(object sender, EventArgs e)
    204  - {
    205  - // This happens when the user exit the process
    206  - IsConnected = false;
    207  - }
     200 + IsConnecting = false;
     201 + }
    208 202   
    209  - public void FocusEmbeddedWindow()
    210  - {
    211  - if (IsConnected)
    212  - NativeMethods.SetForegroundWindow(_process.MainWindowHandle);
    213  - }
     203 + private void Process_Exited(object sender, EventArgs e)
     204 + {
     205 + // This happens when the user exit the process
     206 + IsConnected = false;
     207 + }
     208 + 
     209 + public void FocusEmbeddedWindow()
     210 + {
     211 + if (IsConnected)
     212 + NativeMethods.SetForegroundWindow(_process.MainWindowHandle);
     213 + }
    214 214   
    215  - public void ResizeEmbeddedWindow()
    216  - {
    217  - if (IsConnected)
    218  - NativeMethods.SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, WindowHost.ClientSize.Width, WindowHost.ClientSize.Height, NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
    219  - }
     215 + public void ResizeEmbeddedWindow()
     216 + {
     217 + if (IsConnected)
     218 + NativeMethods.SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, WindowHost.ClientSize.Width, WindowHost.ClientSize.Height, NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
     219 + }
    220 220   
    221  - public void Disconnect()
    222  - {
    223  - if (IsConnected)
    224  - _process.Kill();
    225  - }
     221 + public void Disconnect()
     222 + {
     223 + if (IsConnected)
     224 + _process.Kill();
     225 + }
    226 226   
    227  - private void Reconnect()
    228  - {
    229  - if (IsConnected)
    230  - Disconnect();
     227 + private void Reconnect()
     228 + {
     229 + if (IsConnected)
     230 + Disconnect();
    231 231   
    232  - Connect();
    233  - }
     232 + Connect();
     233 + }
    234 234   
    235  - public void CloseTab()
    236  - {
    237  - _closing = true;
     235 + public void CloseTab()
     236 + {
     237 + _closing = true;
    238 238   
    239  - Disconnect();
    240  - }
    241  - #endregion
     239 + Disconnect();
     240 + }
     241 + #endregion
    242 242   
    243  - #region Events
    244  - private void WindowGrid_SizeChanged(object sender, SizeChangedEventArgs e)
    245  - {
    246  - if (IsConnected)
    247  - ResizeEmbeddedWindow();
    248  - }
    249  - #endregion
     243 + #region Events
     244 + private void WindowGrid_SizeChanged(object sender, SizeChangedEventArgs e)
     245 + {
     246 + if (IsConnected)
     247 + ResizeEmbeddedWindow();
    250 248   }
     249 + #endregion
    251 250  }
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/PuTTYControl.xaml.cs
    skipped 13 lines
    14 14  using NETworkManager.Settings;
    15 15  using PuTTY = NETworkManager.Models.PuTTY.PuTTY;
    16 16   
    17  -namespace NETworkManager.Controls
     17 +namespace NETworkManager.Controls;
     18 + 
     19 +public partial class PuTTYControl : INotifyPropertyChanged
    18 20  {
    19  - public partial class PuTTYControl : INotifyPropertyChanged
     21 + #region PropertyChangedEventHandler
     22 + public event PropertyChangedEventHandler PropertyChanged;
     23 + 
     24 + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    20 25   {
    21  - #region PropertyChangedEventHandler
    22  - public event PropertyChangedEventHandler PropertyChanged;
     26 + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     27 + }
     28 + #endregion
    23 29   
    24  - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    25  - {
    26  - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    27  - }
    28  - #endregion
    29  - 
    30  - #region Variables
    31  - private bool _initialized;
    32  - private bool _closing; // When the tab is closed --> OnClose()
     30 + #region Variables
     31 + private bool _initialized;
     32 + private bool _closing; // When the tab is closed --> OnClose()
    33 33   
    34  - private readonly IDialogCoordinator _dialogCoordinator;
     34 + private readonly IDialogCoordinator _dialogCoordinator;
    35 35   
    36  - private readonly PuTTYSessionInfo _sessionInfo;
     36 + private readonly PuTTYSessionInfo _sessionInfo;
    37 37   
    38  - private Process _process;
    39  - private IntPtr _appWin;
     38 + private Process _process;
     39 + private IntPtr _appWin;
    40 40   
    41  - private bool _isConnected;
    42  - public bool IsConnected
     41 + private bool _isConnected;
     42 + public bool IsConnected
     43 + {
     44 + get => _isConnected;
     45 + set
    43 46   {
    44  - get => _isConnected;
    45  - set
    46  - {
    47  - if (value == _isConnected)
    48  - return;
     47 + if (value == _isConnected)
     48 + return;
    49 49   
    50  - _isConnected = value;
    51  - OnPropertyChanged();
    52  - }
     50 + _isConnected = value;
     51 + OnPropertyChanged();
    53 52   }
     53 + }
    54 54   
    55  - private bool _isConnecting;
    56  - public bool IsConnecting
     55 + private bool _isConnecting;
     56 + public bool IsConnecting
     57 + {
     58 + get => _isConnecting;
     59 + set
    57 60   {
    58  - get => _isConnecting;
    59  - set
    60  - {
    61  - if (value == _isConnecting)
    62  - return;
     61 + if (value == _isConnecting)
     62 + return;
    63 63   
    64  - _isConnecting = value;
    65  - OnPropertyChanged();
    66  - }
     64 + _isConnecting = value;
     65 + OnPropertyChanged();
    67 66   }
    68  - #endregion
     67 + }
     68 + #endregion
    69 69   
    70  - #region Constructor, load
    71  - public PuTTYControl(PuTTYSessionInfo info)
    72  - {
    73  - InitializeComponent();
    74  - DataContext = this;
     70 + #region Constructor, load
     71 + public PuTTYControl(PuTTYSessionInfo info)
     72 + {
     73 + InitializeComponent();
     74 + DataContext = this;
    75 75   
    76  - _dialogCoordinator = DialogCoordinator.Instance;
     76 + _dialogCoordinator = DialogCoordinator.Instance;
    77 77   
    78  - _sessionInfo = info;
     78 + _sessionInfo = info;
    79 79   
    80  - Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
    81  - }
     80 + Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
     81 + }
    82 82   
    83  - private void UserControl_Loaded(object sender, RoutedEventArgs e)
    84  - {
    85  - // Connect after the control is drawn and only on the first init
    86  - if (_initialized)
    87  - return;
     83 + private void UserControl_Loaded(object sender, RoutedEventArgs e)
     84 + {
     85 + // Connect after the control is drawn and only on the first init
     86 + if (_initialized)
     87 + return;
    88 88   
    89  - // Fix: The control is not visible by default, thus height and width is not set. If the values are not set, the size does not scale properly
    90  - WindowHost.Height = (int)ActualHeight;
    91  - WindowHost.Width = (int)ActualWidth;
     89 + // Fix: The control is not visible by default, thus height and width is not set. If the values are not set, the size does not scale properly
     90 + WindowHost.Height = (int)ActualHeight;
     91 + WindowHost.Width = (int)ActualWidth;
    92 92   
    93  - Connect();
     93 + Connect();
    94 94   
    95  - _initialized = true;
    96  - }
     95 + _initialized = true;
     96 + }
    97 97   
    98  - private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
    99  - {
    100  - CloseTab();
    101  - }
    102  - #endregion
     98 + private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
     99 + {
     100 + CloseTab();
     101 + }
     102 + #endregion
    103 103   
    104  - #region ICommands & Actions
    105  - public ICommand ReconnectCommand
    106  - {
    107  - get { return new RelayCommand(p => ReconnectAction()); }
    108  - }
     104 + #region ICommands & Actions
     105 + public ICommand ReconnectCommand
     106 + {
     107 + get { return new RelayCommand(p => ReconnectAction()); }
     108 + }
    109 109   
    110  - private void ReconnectAction()
    111  - {
    112  - Reconnect();
    113  - }
    114  - #endregion
     110 + private void ReconnectAction()
     111 + {
     112 + Reconnect();
     113 + }
     114 + #endregion
     115 + 
     116 + #region Methods
     117 + private async Task Connect()
     118 + {
     119 + IsConnecting = true;
     120 + 
     121 + // Create log path
     122 + DirectoryHelper.CreateWithEnvironmentVariables(_sessionInfo.LogPath);
    115 123   
    116  - #region Methods
    117  - private async Task Connect()
     124 + var info = new ProcessStartInfo
    118 125   {
    119  - IsConnecting = true;
     126 + FileName = _sessionInfo.ApplicationFilePath,
     127 + Arguments = PuTTY.BuildCommandLine(_sessionInfo)
     128 + };
    120 129   
    121  - // Create log path
    122  - DirectoryHelper.CreateWithEnvironmentVariables(_sessionInfo.LogPath);
     130 + try
     131 + {
     132 + _process = Process.Start(info);
    123 133   
    124  - var info = new ProcessStartInfo
     134 + if (_process != null)
    125 135   {
    126  - FileName = _sessionInfo.ApplicationFilePath,
    127  - Arguments = PuTTY.BuildCommandLine(_sessionInfo)
    128  - };
     136 + _process.EnableRaisingEvents = true;
     137 + _process.Exited += Process_Exited;
    129 138   
    130  - try
    131  - {
    132  - _process = Process.Start(info);
     139 + _appWin = _process.MainWindowHandle;
    133 140   
    134  - if (_process != null)
     141 + if (_appWin == IntPtr.Zero)
    135 142   {
    136  - _process.EnableRaisingEvents = true;
    137  - _process.Exited += Process_Exited;
     143 + var startTime = DateTime.Now;
    138 144   
    139  - _appWin = _process.MainWindowHandle;
    140  - 
    141  - if (_appWin == IntPtr.Zero)
     145 + while ((DateTime.Now - startTime).TotalSeconds < 10)
    142 146   {
    143  - var startTime = DateTime.Now;
     147 + _process.Refresh();
    144 148  
    145  - while ((DateTime.Now - startTime).TotalSeconds < 10)
    146  - {
    147  - _process.Refresh();
     149 + if (_process.HasExited)
     150 + break;
    148 151  
    149  - if (_process.HasExited)
    150  - break;
    151 152   
     153 + _appWin = _process.MainWindowHandle;
    152 154   
    153  - _appWin = _process.MainWindowHandle;
     155 + if (IntPtr.Zero != _appWin)
     156 + break;
    154 157   
    155  - if (IntPtr.Zero != _appWin)
    156  - break;
    157  - 
    158  - await Task.Delay(100);
    159  - }
     158 + await Task.Delay(100);
    160 159   }
     160 + }
    161 161   
    162  - if (_appWin != IntPtr.Zero)
     162 + if (_appWin != IntPtr.Zero)
     163 + {
     164 + while (!_process.HasExited && _process.MainWindowTitle.IndexOf(" - PuTTY", StringComparison.Ordinal) == -1)
    163 165   {
    164  - while (!_process.HasExited && _process.MainWindowTitle.IndexOf(" - PuTTY", StringComparison.Ordinal) == -1)
    165  - {
    166  - await Task.Delay(100);
     166 + await Task.Delay(100);
    167 167   
    168  - _process.Refresh();
    169  - }
     168 + _process.Refresh();
     169 + }
    170 170   
    171  - if (!_process.HasExited)
    172  - {
    173  - NativeMethods.SetParent(_appWin, WindowHost.Handle);
     171 + if (!_process.HasExited)
     172 + {
     173 + NativeMethods.SetParent(_appWin, WindowHost.Handle);
    174 174   
    175  - // Show window before set style and resize
    176  - NativeMethods.ShowWindow(_appWin, NativeMethods.WindowShowStyle.Maximize);
     175 + // Show window before set style and resize
     176 + NativeMethods.ShowWindow(_appWin, NativeMethods.WindowShowStyle.Maximize);
    177 177   
    178  - // Remove border etc.
    179  - long style = (int)NativeMethods.GetWindowLong(_appWin, NativeMethods.GWL_STYLE);
    180  - style &= ~(NativeMethods.WS_CAPTION | NativeMethods.WS_POPUP | NativeMethods.WS_THICKFRAME); // NativeMethods.WS_POPUP --> Overflow? (https://github.com/BornToBeRoot/NETworkManager/issues/167)
    181  - NativeMethods.SetWindowLongPtr(_appWin, NativeMethods.GWL_STYLE, new IntPtr(style));
     178 + // Remove border etc.
     179 + long style = (int)NativeMethods.GetWindowLong(_appWin, NativeMethods.GWL_STYLE);
     180 + style &= ~(NativeMethods.WS_CAPTION | NativeMethods.WS_POPUP | NativeMethods.WS_THICKFRAME); // NativeMethods.WS_POPUP --> Overflow? (https://github.com/BornToBeRoot/NETworkManager/issues/167)
     181 + NativeMethods.SetWindowLongPtr(_appWin, NativeMethods.GWL_STYLE, new IntPtr(style));
    182 182   
    183  - IsConnected = true;
     183 + IsConnected = true;
    184 184   
    185  - // Resize embedded application & refresh
    186  - // Requires a short delay because it's not applied immediately
    187  - await Task.Delay(250);
     185 + // Resize embedded application & refresh
     186 + // Requires a short delay because it's not applied immediately
     187 + await Task.Delay(250);
    188 188  
    189  - ResizeEmbeddedWindow();
    190  - }
     189 + ResizeEmbeddedWindow();
    191 190   }
    192 191   }
    193  - else
    194  - {
    195  - throw new Exception("Process could not be started!");
    196  - }
    197 192   }
    198  - catch (Exception ex)
     193 + else
    199 194   {
    200  - if (!_closing)
    201  - {
    202  - var settings = AppearanceManager.MetroDialog;
    203  - settings.AffirmativeButtonText = Localization.Resources.Strings.OK;
     195 + throw new Exception("Process could not be started!");
     196 + }
     197 + }
     198 + catch (Exception ex)
     199 + {
     200 + if (!_closing)
     201 + {
     202 + var settings = AppearanceManager.MetroDialog;
     203 + settings.AffirmativeButtonText = Localization.Resources.Strings.OK;
    204 204   
    205  - ConfigurationManager.Current.IsDialogOpen = true;
     205 + ConfigurationManager.Current.IsDialogOpen = true;
    206 206   
    207  - await _dialogCoordinator.ShowMessageAsync(this, NETworkManager.Localization.Resources.Strings.Error,
    208  - ex.Message, MessageDialogStyle.Affirmative, settings);
     207 + await _dialogCoordinator.ShowMessageAsync(this, NETworkManager.Localization.Resources.Strings.Error,
     208 + ex.Message, MessageDialogStyle.Affirmative, settings);
    209 209   
    210  - ConfigurationManager.Current.IsDialogOpen = false;
    211  - }
     210 + ConfigurationManager.Current.IsDialogOpen = false;
    212 211   }
     212 + }
    213 213   
    214  - IsConnecting = false;
    215  - }
     214 + IsConnecting = false;
     215 + }
    216 216   
    217  - private void Process_Exited(object sender, EventArgs e)
    218  - {
    219  - // This happens when the user exit the process
    220  - IsConnected = false;
    221  - }
     217 + private void Process_Exited(object sender, EventArgs e)
     218 + {
     219 + // This happens when the user exit the process
     220 + IsConnected = false;
     221 + }
    222 222   
    223  - public void FocusEmbeddedWindow()
    224  - {
    225  - if (IsConnected)
    226  - NativeMethods.SetForegroundWindow(_process.MainWindowHandle);
    227  - }
     223 + public void FocusEmbeddedWindow()
     224 + {
     225 + if (IsConnected)
     226 + NativeMethods.SetForegroundWindow(_process.MainWindowHandle);
     227 + }
    228 228   
    229  - public void ResizeEmbeddedWindow()
    230  - {
    231  - if (IsConnected)
    232  - NativeMethods.SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, WindowHost.ClientSize.Width, WindowHost.ClientSize.Height, NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
    233  - }
     229 + public void ResizeEmbeddedWindow()
     230 + {
     231 + if (IsConnected)
     232 + NativeMethods.SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, WindowHost.ClientSize.Width, WindowHost.ClientSize.Height, NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
     233 + }
    234 234   
    235  - public void Disconnect()
    236  - {
    237  - if (IsConnected)
    238  - _process.Kill();
    239  - }
     235 + public void Disconnect()
     236 + {
     237 + if (IsConnected)
     238 + _process.Kill();
     239 + }
    240 240   
    241  - private void Reconnect()
    242  - {
    243  - if (IsConnected)
    244  - Disconnect();
     241 + private void Reconnect()
     242 + {
     243 + if (IsConnected)
     244 + Disconnect();
    245 245   
    246  - Connect();
    247  - }
     246 + Connect();
     247 + }
    248 248   
    249  - public void RestartSession()
    250  - {
    251  - if (IsConnected)
    252  - NativeMethods.SendMessage(_process.MainWindowHandle, (uint)NativeMethods.WM.SYSCOMMAND, new IntPtr(64), new IntPtr(0));
    253  - }
     249 + public void RestartSession()
     250 + {
     251 + if (IsConnected)
     252 + NativeMethods.SendMessage(_process.MainWindowHandle, (uint)NativeMethods.WM.SYSCOMMAND, new IntPtr(64), new IntPtr(0));
     253 + }
    254 254   
    255  - public void CloseTab()
    256  - {
    257  - _closing = true;
     255 + public void CloseTab()
     256 + {
     257 + _closing = true;
    258 258   
    259  - Disconnect();
    260  - }
    261  - #endregion
     259 + Disconnect();
     260 + }
     261 + #endregion
    262 262   
    263  - #region Events
    264  - private void WindowGrid_SizeChanged(object sender, SizeChangedEventArgs e)
    265  - {
    266  - if (IsConnected)
    267  - ResizeEmbeddedWindow();
    268  - }
    269  - #endregion
     263 + #region Events
     264 + private void WindowGrid_SizeChanged(object sender, SizeChangedEventArgs e)
     265 + {
     266 + if (IsConnected)
     267 + ResizeEmbeddedWindow();
    270 268   }
     269 + #endregion
    271 270  }
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs
    skipped 8 lines
    9 9  using System.Threading.Tasks;
    10 10  using NETworkManager.Utilities;
    11 11   
    12  -namespace NETworkManager.Controls
     12 +namespace NETworkManager.Controls;
     13 + 
     14 +public partial class RemoteDesktopControl : INotifyPropertyChanged
    13 15  {
    14  - public partial class RemoteDesktopControl : INotifyPropertyChanged
     16 + #region PropertyChangedEventHandler
     17 + public event PropertyChangedEventHandler PropertyChanged;
     18 + 
     19 + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    15 20   {
    16  - #region PropertyChangedEventHandler
    17  - public event PropertyChangedEventHandler PropertyChanged;
     21 + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     22 + }
     23 + #endregion
    18 24   
    19  - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    20  - {
    21  - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    22  - }
    23  - #endregion
    24  - 
    25  - #region Variables
    26  - private bool _initialized;
     25 + #region Variables
     26 + private bool _initialized;
    27 27   
    28  - private readonly RemoteDesktopSessionInfo _rdpSessionInfo;
     28 + private readonly RemoteDesktopSessionInfo _rdpSessionInfo;
    29 29   
    30  - // Fix WindowsFormsHost width
    31  - private double _rdpClientWidth;
    32  - public double RdpClientWidth
     30 + // Fix WindowsFormsHost width
     31 + private double _rdpClientWidth;
     32 + public double RdpClientWidth
     33 + {
     34 + get => _rdpClientWidth;
     35 + set
    33 36   {
    34  - get => _rdpClientWidth;
    35  - set
    36  - {
    37  - if (value == _rdpClientWidth)
    38  - return;
     37 + if (value == _rdpClientWidth)
     38 + return;
    39 39   
    40  - _rdpClientWidth = value;
    41  - OnPropertyChanged();
    42  - }
     40 + _rdpClientWidth = value;
     41 + OnPropertyChanged();
    43 42   }
     43 + }
    44 44   
    45  - // Fix WindowsFormsHost height
    46  - private double _rdpClientHeight;
    47  - public double RdpClientHeight
     45 + // Fix WindowsFormsHost height
     46 + private double _rdpClientHeight;
     47 + public double RdpClientHeight
     48 + {
     49 + get => _rdpClientHeight;
     50 + set
    48 51   {
    49  - get => _rdpClientHeight;
    50  - set
    51  - {
    52  - if (value == _rdpClientHeight)
    53  - return;
     52 + if (value == _rdpClientHeight)
     53 + return;
    54 54   
    55  - _rdpClientHeight = value;
    56  - OnPropertyChanged();
    57  - }
     55 + _rdpClientHeight = value;
     56 + OnPropertyChanged();
    58 57   }
     58 + }
    59 59   
    60  - private bool _isConnected;
    61  - public bool IsConnected
     60 + private bool _isConnected;
     61 + public bool IsConnected
     62 + {
     63 + get => _isConnected;
     64 + set
    62 65   {
    63  - get => _isConnected;
    64  - set
    65  - {
    66  - if (value == _isConnected)
    67  - return;
     66 + if (value == _isConnected)
     67 + return;
    68 68   
    69  - _isConnected = value;
    70  - OnPropertyChanged();
    71  - }
     69 + _isConnected = value;
     70 + OnPropertyChanged();
    72 71   }
     72 + }
    73 73   
    74  - private bool _isConnecting;
    75  - public bool IsConnecting
     74 + private bool _isConnecting;
     75 + public bool IsConnecting
     76 + {
     77 + get => _isConnecting;
     78 + set
    76 79   {
    77  - get => _isConnecting;
    78  - set
    79  - {
    80  - if (value == _isConnecting)
    81  - return;
     80 + if (value == _isConnecting)
     81 + return;
    82 82   
    83  - _isConnecting = value;
    84  - OnPropertyChanged();
    85  - }
     83 + _isConnecting = value;
     84 + OnPropertyChanged();
    86 85   }
     86 + }
    87 87   
    88  - private string _disconnectReason;
    89  - public string DisconnectReason
     88 + private string _disconnectReason;
     89 + public string DisconnectReason
     90 + {
     91 + get => _disconnectReason;
     92 + set
    90 93   {
    91  - get => _disconnectReason;
    92  - set
    93  - {
    94  - if (value == _disconnectReason)
    95  - return;
     94 + if (value == _disconnectReason)
     95 + return;
    96 96   
    97  - _disconnectReason = value;
    98  - OnPropertyChanged();
    99  - }
     97 + _disconnectReason = value;
     98 + OnPropertyChanged();
    100 99   }
     100 + }
    101 101   
    102  - private bool _isReconnecting;
    103  - public bool IsReconnecting
     102 + private bool _isReconnecting;
     103 + public bool IsReconnecting
     104 + {
     105 + get => _isReconnecting;
     106 + set
    104 107   {
    105  - get => _isReconnecting;
    106  - set
    107  - {
    108  - if (value == _isReconnecting)
    109  - return;
     108 + if (value == _isReconnecting)
     109 + return;
    110 110   
    111  - _isReconnecting = value;
    112  - OnPropertyChanged();
    113  - }
     111 + _isReconnecting = value;
     112 + OnPropertyChanged();
    114 113   }
    115  - #endregion
     114 + }
     115 + #endregion
     116 + 
     117 + #region Constructor, load
     118 + public RemoteDesktopControl(RemoteDesktopSessionInfo info)
     119 + {
     120 + InitializeComponent();
     121 + DataContext = this;
     122 + 
     123 + _rdpSessionInfo = info;
     124 + 
     125 + Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
     126 + }
    116 127   
    117  - #region Constructor, load
    118  - public RemoteDesktopControl(RemoteDesktopSessionInfo info)
    119  - {
    120  - InitializeComponent();
    121  - DataContext = this;
     128 + private void UserControl_Loaded(object sender, RoutedEventArgs e)
     129 + {
     130 + // Connect after the control is drawn and only on the first init
     131 + if (_initialized)
     132 + return;
    122 133   
    123  - _rdpSessionInfo = info;
     134 + Connect();
     135 + _initialized = true;
     136 + }
     137 + 
     138 + private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
     139 + {
     140 + CloseTab();
     141 + }
     142 + #endregion
    124 143   
    125  - Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
    126  - }
     144 + #region ICommands & Actions
     145 + public ICommand ReconnectCommand
     146 + {
     147 + get { return new RelayCommand(p => ReconnectAction()); }
     148 + }
    127 149   
    128  - private void UserControl_Loaded(object sender, RoutedEventArgs e)
    129  - {
    130  - // Connect after the control is drawn and only on the first init
    131  - if (_initialized)
    132  - return;
     150 + private void ReconnectAction()
     151 + {
     152 + Reconnect();
     153 + }
    133 154   
    134  - Connect();
    135  - _initialized = true;
    136  - }
     155 + public ICommand DisconnectCommand
     156 + {
     157 + get { return new RelayCommand(p => DisconnectAction()); }
     158 + }
    137 159   
    138  - private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
    139  - {
    140  - CloseTab();
    141  - }
    142  - #endregion
     160 + private void DisconnectAction()
     161 + {
     162 + Disconnect();
     163 + }
     164 + #endregion
    143 165   
    144  - #region ICommands & Actions
    145  - public ICommand ReconnectCommand
    146  - {
    147  - get { return new RelayCommand(p => ReconnectAction()); }
    148  - }
     166 + #region Methods
     167 + private void Connect()
     168 + {
     169 + IsConnecting = true;
    149 170   
    150  - private void ReconnectAction()
    151  - {
    152  - Reconnect();
    153  - }
     171 + RdpClient.CreateControl();
    154 172   
    155  - public ICommand DisconnectCommand
    156  - {
    157  - get { return new RelayCommand(p => DisconnectAction()); }
    158  - }
     173 + RdpClient.Server = _rdpSessionInfo.Hostname;
     174 + RdpClient.AdvancedSettings9.RDPPort = _rdpSessionInfo.Port;
    159 175   
    160  - private void DisconnectAction()
     176 + if (_rdpSessionInfo.CustomCredentials)
    161 177   {
    162  - Disconnect();
     178 + RdpClient.UserName = _rdpSessionInfo.Username;
     179 + RdpClient.AdvancedSettings9.ClearTextPassword = SecureStringHelper.ConvertToString(_rdpSessionInfo.Password);
    163 180   }
    164  - #endregion
    165 181   
    166  - #region Methods
    167  - private void Connect()
    168  - {
    169  - IsConnecting = true;
     182 + // AdvancedSettings
     183 + RdpClient.AdvancedSettings9.AuthenticationLevel = _rdpSessionInfo.AuthenticationLevel;
     184 + RdpClient.AdvancedSettings9.EnableCredSspSupport = _rdpSessionInfo.EnableCredSspSupport;
    170 185   
    171  - RdpClient.CreateControl();
     186 + // Keyboard
     187 + RdpClient.SecuredSettings3.KeyboardHookMode = (int)_rdpSessionInfo.KeyboardHookMode;
    172 188   
    173  - RdpClient.Server = _rdpSessionInfo.Hostname;
    174  - RdpClient.AdvancedSettings9.RDPPort = _rdpSessionInfo.Port;
     189 + // Devices and resources
     190 + RdpClient.AdvancedSettings9.RedirectClipboard = _rdpSessionInfo.RedirectClipboard;
     191 + RdpClient.AdvancedSettings9.RedirectDevices = _rdpSessionInfo.RedirectDevices;
     192 + RdpClient.AdvancedSettings9.RedirectDrives = _rdpSessionInfo.RedirectDrives;
     193 + RdpClient.AdvancedSettings9.RedirectPorts = _rdpSessionInfo.RedirectPorts;
     194 + RdpClient.AdvancedSettings9.RedirectSmartCards = _rdpSessionInfo.RedirectSmartCards;
     195 + RdpClient.AdvancedSettings9.RedirectPrinters = _rdpSessionInfo.RedirectPrinters;
    175 196   
    176  - if (_rdpSessionInfo.CustomCredentials)
    177  - {
    178  - RdpClient.UserName = _rdpSessionInfo.Username;
    179  - RdpClient.AdvancedSettings9.ClearTextPassword = SecureStringHelper.ConvertToString(_rdpSessionInfo.Password);
    180  - }
     197 + // Audio
     198 + RdpClient.AdvancedSettings9.AudioRedirectionMode = (uint)_rdpSessionInfo.AudioRedirectionMode;
     199 + RdpClient.AdvancedSettings9.AudioCaptureRedirectionMode = _rdpSessionInfo.AudioCaptureRedirectionMode == 0;
    181 200   
    182  - // AdvancedSettings
    183  - RdpClient.AdvancedSettings9.AuthenticationLevel = _rdpSessionInfo.AuthenticationLevel;
    184  - RdpClient.AdvancedSettings9.EnableCredSspSupport = _rdpSessionInfo.EnableCredSspSupport;
     201 + // Performance
     202 + RdpClient.AdvancedSettings9.BitmapPeristence = _rdpSessionInfo.PersistentBitmapCaching ? 1 : 0;
     203 + RdpClient.AdvancedSettings9.EnableAutoReconnect = _rdpSessionInfo.ReconnectIfTheConnectionIsDropped;
    185 204   
    186  - // Keyboard
    187  - RdpClient.SecuredSettings3.KeyboardHookMode = (int)_rdpSessionInfo.KeyboardHookMode;
     205 + // Experience
     206 + if (_rdpSessionInfo.NetworkConnectionType != 0)
     207 + {
     208 + RdpClient.AdvancedSettings9.NetworkConnectionType = (uint)_rdpSessionInfo.NetworkConnectionType;
    188 209   
    189  - // Devices and resources
    190  - RdpClient.AdvancedSettings9.RedirectClipboard = _rdpSessionInfo.RedirectClipboard;
    191  - RdpClient.AdvancedSettings9.RedirectDevices = _rdpSessionInfo.RedirectDevices;
    192  - RdpClient.AdvancedSettings9.RedirectDrives = _rdpSessionInfo.RedirectDrives;
    193  - RdpClient.AdvancedSettings9.RedirectPorts = _rdpSessionInfo.RedirectPorts;
    194  - RdpClient.AdvancedSettings9.RedirectSmartCards = _rdpSessionInfo.RedirectSmartCards;
    195  - RdpClient.AdvancedSettings9.RedirectPrinters = _rdpSessionInfo.RedirectPrinters;
     210 + if (!_rdpSessionInfo.DesktopBackground)
     211 + RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_DISABLE_WALLPAPER;
    196 212   
    197  - // Audio
    198  - RdpClient.AdvancedSettings9.AudioRedirectionMode = (uint)_rdpSessionInfo.AudioRedirectionMode;
    199  - RdpClient.AdvancedSettings9.AudioCaptureRedirectionMode = _rdpSessionInfo.AudioCaptureRedirectionMode == 0;
     213 + if (_rdpSessionInfo.FontSmoothing)
     214 + RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_ENABLE_FONT_SMOOTHING;
    200 215   
    201  - // Performance
    202  - RdpClient.AdvancedSettings9.BitmapPeristence = _rdpSessionInfo.PersistentBitmapCaching ? 1 : 0;
    203  - RdpClient.AdvancedSettings9.EnableAutoReconnect = _rdpSessionInfo.ReconnectIfTheConnectionIsDropped;
     216 + if (_rdpSessionInfo.DesktopComposition)
     217 + RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_ENABLE_DESKTOP_COMPOSITION;
    204 218   
    205  - // Experience
    206  - if (_rdpSessionInfo.NetworkConnectionType != 0)
    207  - {
    208  - RdpClient.AdvancedSettings9.NetworkConnectionType = (uint)_rdpSessionInfo.NetworkConnectionType;
     219 + if (!_rdpSessionInfo.ShowWindowContentsWhileDragging)
     220 + RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_DISABLE_FULLWINDOWDRAG;
    209 221   
    210  - if (!_rdpSessionInfo.DesktopBackground)
    211  - RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_DISABLE_WALLPAPER;
     222 + if (!_rdpSessionInfo.MenuAndWindowAnimation)
     223 + RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_DISABLE_MENUANIMATIONS;
    212 224   
    213  - if (_rdpSessionInfo.FontSmoothing)
    214  - RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_ENABLE_FONT_SMOOTHING;
     225 + if (!_rdpSessionInfo.VisualStyles)
     226 + RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_DISABLE_THEMING;
     227 + }
    215 228   
    216  - if (_rdpSessionInfo.DesktopComposition)
    217  - RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_ENABLE_DESKTOP_COMPOSITION;
     229 + // Display
     230 + RdpClient.ColorDepth = _rdpSessionInfo.ColorDepth; // 8, 15, 16, 24
    218 231   
    219  - if (!_rdpSessionInfo.ShowWindowContentsWhileDragging)
    220  - RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_DISABLE_FULLWINDOWDRAG;
     232 + if (_rdpSessionInfo.AdjustScreenAutomatically || _rdpSessionInfo.UseCurrentViewSize)
     233 + {
     234 + RdpClient.DesktopWidth = (int)RdpGrid.ActualWidth;
     235 + RdpClient.DesktopHeight = (int)RdpGrid.ActualHeight;
     236 + }
     237 + else
     238 + {
     239 + RdpClient.DesktopWidth = _rdpSessionInfo.DesktopWidth;
     240 + RdpClient.DesktopHeight = _rdpSessionInfo.DesktopHeight;
     241 + }
    221 242   
    222  - if (!_rdpSessionInfo.MenuAndWindowAnimation)
    223  - RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_DISABLE_MENUANIMATIONS;
     243 + FixWindowsFormsHostSize();
    224 244   
    225  - if (!_rdpSessionInfo.VisualStyles)
    226  - RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_DISABLE_THEMING;
    227  - }
     245 + // Events
     246 + RdpClient.OnConnected += RdpClient_OnConnected;
     247 + RdpClient.OnDisconnected += RdpClient_OnDisconnected;
    228 248   
    229  - // Display
    230  - RdpClient.ColorDepth = _rdpSessionInfo.ColorDepth; // 8, 15, 16, 24
     249 + RdpClient.AdvancedSettings9.EnableWindowsKey = 1; // Enable window key
     250 + RdpClient.AdvancedSettings9.allowBackgroundInput = 1; // Background input to send keystrokes like ctrl+alt+del
    231 251   
    232  - if (_rdpSessionInfo.AdjustScreenAutomatically || _rdpSessionInfo.UseCurrentViewSize)
    233  - {
    234  - RdpClient.DesktopWidth = (int)RdpGrid.ActualWidth;
    235  - RdpClient.DesktopHeight = (int)RdpGrid.ActualHeight;
    236  - }
    237  - else
    238  - {
    239  - RdpClient.DesktopWidth = _rdpSessionInfo.DesktopWidth;
    240  - RdpClient.DesktopHeight = _rdpSessionInfo.DesktopHeight;
    241  - }
     252 + RdpClient.Connect();
     253 + }
    242 254   
    243  - FixWindowsFormsHostSize();
     255 + private void Reconnect()
     256 + {
     257 + if (IsConnected)
     258 + return;
    244 259   
    245  - // Events
    246  - RdpClient.OnConnected += RdpClient_OnConnected;
    247  - RdpClient.OnDisconnected += RdpClient_OnDisconnected;
     260 + IsConnecting = true;
    248 261   
    249  - RdpClient.AdvancedSettings9.EnableWindowsKey = 1; // Enable window key
    250  - RdpClient.AdvancedSettings9.allowBackgroundInput = 1; // Background input to send keystrokes like ctrl+alt+del
    251  - 
    252  - RdpClient.Connect();
     262 + if (_rdpSessionInfo.AdjustScreenAutomatically)
     263 + {
     264 + RdpClient.DesktopWidth = (int)RdpGrid.ActualWidth;
     265 + RdpClient.DesktopHeight = (int)RdpGrid.ActualHeight;
    253 266   }
    254 267   
    255  - private void Reconnect()
    256  - {
    257  - if (IsConnected)
    258  - return;
     268 + FixWindowsFormsHostSize();
    259 269   
    260  - IsConnecting = true;
     270 + RdpClient.Connect();
     271 + }
    261 272   
    262  - if (_rdpSessionInfo.AdjustScreenAutomatically)
    263  - {
    264  - RdpClient.DesktopWidth = (int)RdpGrid.ActualWidth;
    265  - RdpClient.DesktopHeight = (int)RdpGrid.ActualHeight;
    266  - }
     273 + public void FullScreen()
     274 + {
     275 + if (!IsConnected)
     276 + return;
    267 277   
    268  - FixWindowsFormsHostSize();
     278 + RdpClient.FullScreen = true;
     279 + }
    269 280   
    270  - RdpClient.Connect();
    271  - }
     281 + public void AdjustScreen()
     282 + {
     283 + if (!IsConnected)
     284 + return;
    272 285   
    273  - public void FullScreen()
    274  - {
    275  - if (!IsConnected)
    276  - return;
     286 + RdpClient.Reconnect((uint)RdpGrid.ActualWidth, (uint)RdpGrid.ActualHeight);
    277 287   
    278  - RdpClient.FullScreen = true;
    279  - }
     288 + FixWindowsFormsHostSize();
     289 + }
    280 290   
    281  - public void AdjustScreen()
    282  - {
    283  - if (!IsConnected)
    284  - return;
     291 + private void FixWindowsFormsHostSize()
     292 + {
     293 + RdpClientWidth = RdpClient.DesktopWidth;
     294 + RdpClientHeight = RdpClient.DesktopHeight;
     295 + }
    285 296   
    286  - RdpClient.Reconnect((uint)RdpGrid.ActualWidth, (uint)RdpGrid.ActualHeight);
     297 + public void SendKey(Keystroke keystroke)
     298 + {
     299 + if (!IsConnected)
     300 + return;
    287 301   
    288  - FixWindowsFormsHostSize();
    289  - }
     302 + MSTSCLib.IMsRdpClientNonScriptable ocx = (MSTSCLib.IMsRdpClientNonScriptable)RdpClient.GetOcx();
    290 303   
    291  - private void FixWindowsFormsHostSize()
    292  - {
    293  - RdpClientWidth = RdpClient.DesktopWidth;
    294  - RdpClientHeight = RdpClient.DesktopHeight;
    295  - }
     304 + var info = RemoteDesktop.GetKeystroke(keystroke);
    296 305   
    297  - public void SendKey(Keystroke keystroke)
    298  - {
    299  - if (!IsConnected)
    300  - return;
     306 + RdpClient.Focus();
    301 307   
    302  - MSTSCLib.IMsRdpClientNonScriptable ocx = (MSTSCLib.IMsRdpClientNonScriptable)RdpClient.GetOcx();
     308 + ocx.SendKeys(info.KeyData.Length, info.ArrayKeyUp, info.KeyData);
     309 + }
    303 310   
    304  - var info = RemoteDesktop.GetKeystroke(keystroke);
    305  - 
    306  - RdpClient.Focus();
    307  - 
    308  - ocx.SendKeys(info.KeyData.Length, info.ArrayKeyUp, info.KeyData);
    309  - }
     311 + private void Disconnect()
     312 + {
     313 + if (!IsConnected)
     314 + return;
    310 315   
    311  - private void Disconnect()
    312  - {
    313  - if (!IsConnected)
    314  - return;
     316 + RdpClient.Disconnect();
     317 + }
    315 318   
    316  - RdpClient.Disconnect();
    317  - }
     319 + public void CloseTab()
     320 + {
     321 + Disconnect();
     322 + }
    318 323   
    319  - public void CloseTab()
     324 + private static string GetDisconnectReason(int reason)
     325 + {
     326 + switch (reason)
    320 327   {
    321  - Disconnect();
     328 + case 0:
     329 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_NoInfo;
     330 + case 1:
     331 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_LocalNotError;
     332 + case 2:
     333 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_RemoteByUser;
     334 + case 3:
     335 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ByServer;
     336 + case 4:
     337 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_TotalLoginTimeLimitReached;
     338 + case 260:
     339 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_DNSLookupFailed;
     340 + case 262:
     341 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory;
     342 + case 264:
     343 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ConnectionTimedOut;
     344 + case 516:
     345 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SocketConnectFailed;
     346 + case 518:
     347 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory2;
     348 + case 520:
     349 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_HostNotFound;
     350 + case 772:
     351 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_WinsockSendFailed;
     352 + case 774:
     353 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory3;
     354 + case 776:
     355 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidIPAddr;
     356 + case 1028:
     357 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SocketRecvFailed;
     358 + case 1030:
     359 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidSecurityData;
     360 + case 1032:
     361 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalError;
     362 + case 1286:
     363 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidEncryption;
     364 + case 1288:
     365 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_DNSLookupFailed2;
     366 + case 1540:
     367 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_GetHostByNameFailed;
     368 + case 1542:
     369 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidServerSecurityInfo;
     370 + case 1544:
     371 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_TimerError;
     372 + case 1796:
     373 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_TimeoutOccurred;
     374 + case 1798:
     375 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ServerCertificateUnpackErr;
     376 + case 2052:
     377 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidIP;
     378 + case 2055:
     379 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrLogonFailure;
     380 + case 2056:
     381 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_LicensingFailed;
     382 + case 2308:
     383 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_AtClientWinsockFDCLOSE;
     384 + case 2310:
     385 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalSecurityError;
     386 + case 2312:
     387 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_LicensingTimeout;
     388 + case 2566:
     389 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalSecurityError2;
     390 + case 2567:
     391 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrNoSuchUser;
     392 + case 2822:
     393 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_EncryptionError;
     394 + case 2823:
     395 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountDisabled;
     396 + case 3078:
     397 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_DecryptionError;
     398 + case 3079:
     399 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountRestriction;
     400 + case 3080:
     401 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ClientDecompressionError;
     402 + case 3335:
     403 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountLockedOut;
     404 + case 3591:
     405 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountExpired;
     406 + case 3847:
     407 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPasswordExpired;
     408 + case 4360:
     409 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_UnableToReconnectToRemoteSession;
     410 + case 4615:
     411 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPasswordMustChange;
     412 + case 5639:
     413 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrDelegationPolicy;
     414 + case 5895:
     415 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPolicyNTLMOnly;
     416 + case 6151:
     417 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrNoAuthenticatingAuthority;
     418 + case 6919:
     419 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrCertExpired;
     420 + case 7175:
     421 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrSmartcardWrongPIN;
     422 + case 8455:
     423 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrFreshCredRequiredByServer;
     424 + case 8711:
     425 + return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrSmartcardCardBlocked;
     426 + default:
     427 + return "Disconnect reason code " + reason + " not found in resources!" + Environment.NewLine + "(You can report this on GitHub)";
    322 428   }
     429 + }
     430 + #endregion
    323 431   
    324  - private static string GetDisconnectReason(int reason)
    325  - {
    326  - switch (reason)
    327  - {
    328  - case 0:
    329  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_NoInfo;
    330  - case 1:
    331  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_LocalNotError;
    332  - case 2:
    333  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_RemoteByUser;
    334  - case 3:
    335  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ByServer;
    336  - case 4:
    337  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_TotalLoginTimeLimitReached;
    338  - case 260:
    339  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_DNSLookupFailed;
    340  - case 262:
    341  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory;
    342  - case 264:
    343  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ConnectionTimedOut;
    344  - case 516:
    345  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SocketConnectFailed;
    346  - case 518:
    347  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory2;
    348  - case 520:
    349  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_HostNotFound;
    350  - case 772:
    351  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_WinsockSendFailed;
    352  - case 774:
    353  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory3;
    354  - case 776:
    355  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidIPAddr;
    356  - case 1028:
    357  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SocketRecvFailed;
    358  - case 1030:
    359  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidSecurityData;
    360  - case 1032:
    361  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalError;
    362  - case 1286:
    363  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidEncryption;
    364  - case 1288:
    365  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_DNSLookupFailed2;
    366  - case 1540:
    367  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_GetHostByNameFailed;
    368  - case 1542:
    369  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidServerSecurityInfo;
    370  - case 1544:
    371  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_TimerError;
    372  - case 1796:
    373  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_TimeoutOccurred;
    374  - case 1798:
    375  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ServerCertificateUnpackErr;
    376  - case 2052:
    377  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidIP;
    378  - case 2055:
    379  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrLogonFailure;
    380  - case 2056:
    381  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_LicensingFailed;
    382  - case 2308:
    383  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_AtClientWinsockFDCLOSE;
    384  - case 2310:
    385  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalSecurityError;
    386  - case 2312:
    387  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_LicensingTimeout;
    388  - case 2566:
    389  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalSecurityError2;
    390  - case 2567:
    391  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrNoSuchUser;
    392  - case 2822:
    393  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_EncryptionError;
    394  - case 2823:
    395  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountDisabled;
    396  - case 3078:
    397  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_DecryptionError;
    398  - case 3079:
    399  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountRestriction;
    400  - case 3080:
    401  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ClientDecompressionError;
    402  - case 3335:
    403  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountLockedOut;
    404  - case 3591:
    405  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountExpired;
    406  - case 3847:
    407  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPasswordExpired;
    408  - case 4360:
    409  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_UnableToReconnectToRemoteSession;
    410  - case 4615:
    411  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPasswordMustChange;
    412  - case 5639:
    413  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrDelegationPolicy;
    414  - case 5895:
    415  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPolicyNTLMOnly;
    416  - case 6151:
    417  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrNoAuthenticatingAuthority;
    418  - case 6919:
    419  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrCertExpired;
    420  - case 7175:
    421  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrSmartcardWrongPIN;
    422  - case 8455:
    423  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrFreshCredRequiredByServer;
    424  - case 8711:
    425  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrSmartcardCardBlocked;
    426  - default:
    427  - return "Disconnect reason code " + reason + " not found in resources!" + Environment.NewLine + "(You can report this on GitHub)";
    428  - }
    429  - }
    430  - #endregion
     432 + #region Events
     433 + private void RdpClient_OnConnected(object sender, EventArgs e)
     434 + {
     435 + IsConnected = true;
     436 + IsConnecting = false;
     437 + }
    431 438   
    432  - #region Events
    433  - private void RdpClient_OnConnected(object sender, EventArgs e)
    434  - {
    435  - IsConnected = true;
    436  - IsConnecting = false;
    437  - }
     439 + private void RdpClient_OnDisconnected(object sender, AxMSTSCLib.IMsTscAxEvents_OnDisconnectedEvent e)
     440 + {
     441 + IsConnected = false;
     442 + IsConnecting = false;
    438 443   
    439  - private void RdpClient_OnDisconnected(object sender, AxMSTSCLib.IMsTscAxEvents_OnDisconnectedEvent e)
    440  - {
    441  - IsConnected = false;
    442  - IsConnecting = false;
     444 + DisconnectReason = GetDisconnectReason(e.discReason);
     445 + }
    443 446   
    444  - DisconnectReason = GetDisconnectReason(e.discReason);
    445  - }
     447 + private void RdpGrid_SizeChanged(object sender, SizeChangedEventArgs e)
     448 + {
     449 + if (IsConnected && _rdpSessionInfo.AdjustScreenAutomatically && !IsReconnecting)
     450 + InitiateReconnection();
     451 + }
    446 452   
    447  - private void RdpGrid_SizeChanged(object sender, SizeChangedEventArgs e)
    448  - {
    449  - if (IsConnected && _rdpSessionInfo.AdjustScreenAutomatically && !IsReconnecting)
    450  - InitiateReconnection();
    451  - }
     453 + private async Task InitiateReconnection()
     454 + {
     455 + IsReconnecting = true;
    452 456   
    453  - private async Task InitiateReconnection()
     457 + do // Prevent to many requests
    454 458   {
    455  - IsReconnecting = true;
    456  - 
    457  - do // Prevent to many requests
    458  - {
    459  - await Task.Delay(250);
     459 + await Task.Delay(250);
    460 460   
    461  - } while (Mouse.LeftButton == MouseButtonState.Pressed);
     461 + } while (Mouse.LeftButton == MouseButtonState.Pressed);
    462 462   
    463  - AdjustScreen();
     463 + AdjustScreen();
    464 464   
    465  - IsReconnecting = false;
    466  - }
    467  - #endregion
     465 + IsReconnecting = false;
    468 466   }
     467 + #endregion
    469 468  }
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/TightVNCControl.xaml.cs
    skipped 12 lines
    13 13  using MahApps.Metro.Controls.Dialogs;
    14 14  using NETworkManager.Settings;
    15 15   
    16  -namespace NETworkManager.Controls
     16 +namespace NETworkManager.Controls;
     17 + 
     18 +public partial class TigerVNCControl : INotifyPropertyChanged
    17 19  {
    18  - public partial class TigerVNCControl : INotifyPropertyChanged
    19  - {
    20  - #region PropertyChangedEventHandler
    21  - public event PropertyChangedEventHandler PropertyChanged;
     20 + #region PropertyChangedEventHandler
     21 + public event PropertyChangedEventHandler PropertyChanged;
    22 22   
    23  - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    24  - {
    25  - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    26  - }
    27  - #endregion
     23 + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
     24 + {
     25 + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     26 + }
     27 + #endregion
    28 28   
    29  - #region Variables
    30  - private bool _initialized;
    31  - private bool _closing; // When the tab is closed --> OnClose()
     29 + #region Variables
     30 + private bool _initialized;
     31 + private bool _closing; // When the tab is closed --> OnClose()
    32 32   
    33  - private readonly IDialogCoordinator _dialogCoordinator;
     33 + private readonly IDialogCoordinator _dialogCoordinator;
    34 34   
    35  - private readonly TigerVNCSessionInfo _sessionInfo;
     35 + private readonly TigerVNCSessionInfo _sessionInfo;
    36 36   
    37  - private Process _process;
    38  - private IntPtr _appWin;
     37 + private Process _process;
     38 + private IntPtr _appWin;
    39 39   
    40  - private bool _isConnected;
    41  - public bool IsConnected
     40 + private bool _isConnected;
     41 + public bool IsConnected
     42 + {
     43 + get => _isConnected;
     44 + set
    42 45   {
    43  - get => _isConnected;
    44  - set
    45  - {
    46  - if (value == _isConnected)
    47  - return;
     46 + if (value == _isConnected)
     47 + return;
    48 48   
    49  - _isConnected = value;
    50  - OnPropertyChanged();
    51  - }
     49 + _isConnected = value;
     50 + OnPropertyChanged();
    52 51   }
     52 + }
    53 53   
    54  - private bool _isConnecting;
    55  - public bool IsConnecting
     54 + private bool _isConnecting;
     55 + public bool IsConnecting
     56 + {
     57 + get => _isConnecting;
     58 + set
    56 59   {
    57  - get => _isConnecting;
    58  - set
    59  - {
    60  - if (value == _isConnecting)
    61  - return;
     60 + if (value == _isConnecting)
     61 + return;
    62 62   
    63  - _isConnecting = value;
    64  - OnPropertyChanged();
    65  - }
     63 + _isConnecting = value;
     64 + OnPropertyChanged();
    66 65   }
    67  - #endregion
     66 + }
     67 + #endregion
     68 + 
     69 + #region Constructor, load
     70 + public TigerVNCControl(TigerVNCSessionInfo info)
     71 + {
     72 + InitializeComponent();
     73 + DataContext = this;
    68 74   
    69  - #region Constructor, load
    70  - public TigerVNCControl(TigerVNCSessionInfo info)
    71  - {
    72  - InitializeComponent();
    73  - DataContext = this;
     75 + _dialogCoordinator = DialogCoordinator.Instance;
     76 + 
     77 + _sessionInfo = info;
    74 78   
    75  - _dialogCoordinator = DialogCoordinator.Instance;
     79 + Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
     80 + }
    76 81   
    77  - _sessionInfo = info;
     82 + private void UserControl_Loaded(object sender, RoutedEventArgs e)
     83 + {
     84 + // Connect after the control is drawn and only on the first init
     85 + if (_initialized)
     86 + return;
    78 87   
    79  - Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
    80  - }
     88 + // Fix: The control is not visible by default, thus height and width is not set. If the values are not set, the size does not scale properly
     89 + WindowHost.Height = (int)ActualHeight;
     90 + WindowHost.Width = (int)ActualWidth;
    81 91   
    82  - private void UserControl_Loaded(object sender, RoutedEventArgs e)
    83  - {
    84  - // Connect after the control is drawn and only on the first init
    85  - if (_initialized)
    86  - return;
     92 + Connect();
    87 93   
    88  - // Fix: The control is not visible by default, thus height and width is not set. If the values are not set, the size does not scale properly
    89  - WindowHost.Height = (int)ActualHeight;
    90  - WindowHost.Width = (int)ActualWidth;
     94 + _initialized = true;
     95 + }
    91 96   
    92  - Connect();
     97 + private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
     98 + {
     99 + CloseTab();
     100 + }
     101 + #endregion
    93 102   
    94  - _initialized = true;
    95  - }
     103 + #region ICommands & Actions
     104 + public ICommand ReconnectCommand
     105 + {
     106 + get { return new RelayCommand(p => ReconnectAction()); }
     107 + }
    96 108   
    97  - private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
    98  - {
    99  - CloseTab();
    100  - }
    101  - #endregion
     109 + private void ReconnectAction()
     110 + {
     111 + Reconnect();
     112 + }
     113 + #endregion
    102 114   
    103  - #region ICommands & Actions
    104  - public ICommand ReconnectCommand
    105  - {
    106  - get { return new RelayCommand(p => ReconnectAction()); }
    107  - }
     115 + #region Methods
     116 + private async Task Connect()
     117 + {
     118 + IsConnecting = true;
    108 119   
    109  - private void ReconnectAction()
     120 + var info = new ProcessStartInfo
    110 121   {
    111  - Reconnect();
    112  - }
    113  - #endregion
     122 + FileName = _sessionInfo.ApplicationFilePath,
     123 + Arguments = TigerVNC.BuildCommandLine(_sessionInfo)
     124 + };
    114 125   
    115  - #region Methods
    116  - private async Task Connect()
     126 + try
    117 127   {
    118  - IsConnecting = true;
     128 + _process = Process.Start(info);
    119 129   
    120  - var info = new ProcessStartInfo
     130 + if (_process != null)
    121 131   {
    122  - FileName = _sessionInfo.ApplicationFilePath,
    123  - Arguments = TigerVNC.BuildCommandLine(_sessionInfo)
    124  - };
     132 + _process.EnableRaisingEvents = true;
     133 + _process.Exited += Process_Exited;
    125 134   
    126  - try
    127  - {
    128  - _process = Process.Start(info);
     135 + _appWin = _process.MainWindowHandle;
    129 136   
    130  - if (_process != null)
     137 + if (_appWin == IntPtr.Zero)
    131 138   {
    132  - _process.EnableRaisingEvents = true;
    133  - _process.Exited += Process_Exited;
    134  - 
    135  - _appWin = _process.MainWindowHandle;
     139 + var startTime = DateTime.Now;
    136 140   
    137  - if (_appWin == IntPtr.Zero)
     141 + while ((DateTime.Now - startTime).TotalSeconds < 10)
    138 142   {
    139  - var startTime = DateTime.Now;
     143 + _process.Refresh();
    140 144   
    141  - while ((DateTime.Now - startTime).TotalSeconds < 10)
    142  - {
    143  - _process.Refresh();
     145 + if (_process.HasExited)
     146 + break;
    144 147   
    145  - if (_process.HasExited)
    146  - break;
     148 + _appWin = _process.MainWindowHandle;
    147 149   
    148  - _appWin = _process.MainWindowHandle;
     150 + if (IntPtr.Zero != _appWin)
     151 + break;
    149 152   
    150  - if (IntPtr.Zero != _appWin)
    151  - break;
    152  - 
    153  - await Task.Delay(100);
    154  - }
     153 + await Task.Delay(100);
    155 154   }
     155 + }
    156 156   
    157  - if (_appWin != IntPtr.Zero)
     157 + if (_appWin != IntPtr.Zero)
     158 + {
     159 + while (!_process.HasExited && _process.MainWindowTitle.IndexOf(" - TigerVNC", StringComparison.Ordinal) == -1)
    158 160   {
    159  - while (!_process.HasExited && _process.MainWindowTitle.IndexOf(" - TigerVNC", StringComparison.Ordinal) == -1)
    160  - {
    161  - await Task.Delay(100);
     161 + await Task.Delay(100);
    162 162   
    163  - _process.Refresh();
    164  - }
     163 + _process.Refresh();
     164 + }
    165 165   
    166  - if (!_process.HasExited)
    167  - {
    168  - // Update the window handle, it changes when there is an authentication dialog
    169  - _appWin = _process.MainWindowHandle;
     166 + if (!_process.HasExited)
     167 + {
     168 + // Update the window handle, it changes when there is an authentication dialog
     169 + _appWin = _process.MainWindowHandle;
    170 170   
    171  - NativeMethods.SetParent(_appWin, WindowHost.Handle);
     171 + NativeMethods.SetParent(_appWin, WindowHost.Handle);
    172 172   
    173  - // Show window before set style and resize
    174  - NativeMethods.ShowWindow(_appWin, NativeMethods.WindowShowStyle.Maximize);
     173 + // Show window before set style and resize
     174 + NativeMethods.ShowWindow(_appWin, NativeMethods.WindowShowStyle.Maximize);
    175 175   
    176  - // Remove border etc.
    177  - long style = (int)NativeMethods.GetWindowLong(_appWin, NativeMethods.GWL_STYLE);
    178  - style &= ~(NativeMethods.WS_CAPTION | NativeMethods.WS_POPUP | NativeMethods.WS_THICKFRAME); // NativeMethods.WS_POPUP --> Overflow? (https://github.com/BornToBeRoot/NETworkManager/issues/167)
    179  - NativeMethods.SetWindowLongPtr(_appWin, NativeMethods.GWL_STYLE, new IntPtr(style));
     176 + // Remove border etc.
     177 + long style = (int)NativeMethods.GetWindowLong(_appWin, NativeMethods.GWL_STYLE);
     178 + style &= ~(NativeMethods.WS_CAPTION | NativeMethods.WS_POPUP | NativeMethods.WS_THICKFRAME); // NativeMethods.WS_POPUP --> Overflow? (https://github.com/BornToBeRoot/NETworkManager/issues/167)
     179 + NativeMethods.SetWindowLongPtr(_appWin, NativeMethods.GWL_STYLE, new IntPtr(style));
    180 180   
    181  - IsConnected = true;
     181 + IsConnected = true;
    182 182   
    183  - // Resize embedded application & refresh
    184  - // Requires a short delay because it's not applied immediately
    185  - await Task.Delay(250);
    186  - ResizeEmbeddedWindow();
    187  - }
     183 + // Resize embedded application & refresh
     184 + // Requires a short delay because it's not applied immediately
     185 + await Task.Delay(250);
     186 + ResizeEmbeddedWindow();
    188 187   }
    189  - }
    190  - else
    191  - {
    192  - throw new Exception("Process could not be started!");
    193 188   }
    194 189   }
    195  - catch (Exception ex)
     190 + else
    196 191   {
    197  - if (!_closing)
    198  - {
    199  - var settings = AppearanceManager.MetroDialog;
    200  - settings.AffirmativeButtonText = Localization.Resources.Strings.OK;
    201  - ConfigurationManager.Current.IsDialogOpen = true;
    202  - 
    203  - await _dialogCoordinator.ShowMessageAsync(this, Localization.Resources.Strings.Error,
    204  - ex.Message, MessageDialogStyle.Affirmative, settings);
    205  - 
    206  - ConfigurationManager.Current.IsDialogOpen = false;
    207  - }
     192 + throw new Exception("Process could not be started!");
    208 193   }
    209  - 
    210  - IsConnecting = false;
    211 194   }
    212  - 
    213  - private void Process_Exited(object sender, EventArgs e)
     195 + catch (Exception ex)
    214 196   {
    215  - // This happens when the user exit the process
    216  - IsConnected = false;
    217  - }
     197 + if (!_closing)
     198 + {
     199 + var settings = AppearanceManager.MetroDialog;
     200 + settings.AffirmativeButtonText = Localization.Resources.Strings.OK;
     201 + ConfigurationManager.Current.IsDialogOpen = true;
    218 202   
    219  - private void ResizeEmbeddedWindow()
    220  - {
    221  - if (IsConnected)
    222  - NativeMethods.SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, WindowHost.ClientSize.Width, WindowHost.ClientSize.Height, NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
    223  - }
     203 + await _dialogCoordinator.ShowMessageAsync(this, Localization.Resources.Strings.Error,
     204 + ex.Message, MessageDialogStyle.Affirmative, settings);
    224 205   
    225  - public void Disconnect()
    226  - {
    227  - if (IsConnected)
    228  - _process.Kill();
     206 + ConfigurationManager.Current.IsDialogOpen = false;
     207 + }
    229 208   }
    230 209   
    231  - private void Reconnect()
    232  - {
    233  - if (IsConnected)
    234  - Disconnect();
     210 + IsConnecting = false;
     211 + }
    235 212   
    236  - Connect();
    237  - }
     213 + private void Process_Exited(object sender, EventArgs e)
     214 + {
     215 + // This happens when the user exit the process
     216 + IsConnected = false;
     217 + }
    238 218   
    239  - public void CloseTab()
    240  - {
    241  - _closing = true;
     219 + private void ResizeEmbeddedWindow()
     220 + {
     221 + if (IsConnected)
     222 + NativeMethods.SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, WindowHost.ClientSize.Width, WindowHost.ClientSize.Height, NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
     223 + }
    242 224   
     225 + public void Disconnect()
     226 + {
     227 + if (IsConnected)
     228 + _process.Kill();
     229 + }
     230 + 
     231 + private void Reconnect()
     232 + {
     233 + if (IsConnected)
    243 234   Disconnect();
    244  - }
    245  - #endregion
     235 + 
     236 + Connect();
     237 + }
     238 + 
     239 + public void CloseTab()
     240 + {
     241 + _closing = true;
     242 + 
     243 + Disconnect();
     244 + }
     245 + #endregion
    246 246   
    247  - #region Events
    248  - private void TigerVNCGrid_SizeChanged(object sender, SizeChangedEventArgs e)
    249  - {
    250  - if (IsConnected)
    251  - ResizeEmbeddedWindow();
    252  - }
    253  - #endregion
     247 + #region Events
     248 + private void TigerVNCGrid_SizeChanged(object sender, SizeChangedEventArgs e)
     249 + {
     250 + if (IsConnected)
     251 + ResizeEmbeddedWindow();
    254 252   }
     253 + #endregion
    255 254  }
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/WebConsoleControl.xaml.cs
    skipped 8 lines
    9 9  using Microsoft.Web.WebView2.Core;
    10 10  using NETworkManager.Settings;
    11 11   
    12  -namespace NETworkManager.Controls
     12 +namespace NETworkManager.Controls;
     13 + 
     14 +public partial class WebConsoleControl : INotifyPropertyChanged
    13 15  {
    14  - public partial class WebConsoleControl : INotifyPropertyChanged
     16 + #region PropertyChangedEventHandler
     17 + public event PropertyChangedEventHandler PropertyChanged;
     18 + 
     19 + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    15 20   {
    16  - #region PropertyChangedEventHandler
    17  - public event PropertyChangedEventHandler PropertyChanged;
     21 + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     22 + }
     23 + #endregion
    18 24   
    19  - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    20  - {
    21  - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    22  - }
    23  - #endregion
     25 + #region Variables
     26 + private bool _initialized;
    24 27   
    25  - #region Variables
    26  - private bool _initialized;
     28 + private readonly WebConsoleSessionInfo _sessionInfo;
    27 29   
    28  - private readonly WebConsoleSessionInfo _sessionInfo;
    29  - 
    30  - private bool _isLoading;
    31  - public bool IsLoading
     30 + private bool _isLoading;
     31 + public bool IsLoading
     32 + {
     33 + get => _isLoading;
     34 + set
    32 35   {
    33  - get => _isLoading;
    34  - set
    35  - {
    36  - if (value == _isLoading)
    37  - return;
     36 + if (value == _isLoading)
     37 + return;
    38 38   
    39  - _isLoading = value;
    40  - OnPropertyChanged();
    41  - }
     39 + _isLoading = value;
     40 + OnPropertyChanged();
    42 41   }
     42 + }
    43 43   
    44  - private bool _firstLoad = true;
    45  - public bool FirstLoad
     44 + private bool _firstLoad = true;
     45 + public bool FirstLoad
     46 + {
     47 + get => _firstLoad;
     48 + set
    46 49   {
    47  - get => _firstLoad;
    48  - set
    49  - {
    50  - if (value == _firstLoad)
    51  - return;
     50 + if (value == _firstLoad)
     51 + return;
    52 52   
    53  - _firstLoad = value;
    54  - OnPropertyChanged();
    55  - }
     53 + _firstLoad = value;
     54 + OnPropertyChanged();
    56 55   }
     56 + }
    57 57   
    58  - private string _url;
    59  - public string Url
     58 + private string _url;
     59 + public string Url
     60 + {
     61 + get => _url;
     62 + set
    60 63   {
    61  - get => _url;
    62  - set
    63  - {
    64  - if (value == _url)
    65  - return;
     64 + if (value == _url)
     65 + return;
    66 66   
    67  - _url = value;
    68  - OnPropertyChanged();
    69  - }
     67 + _url = value;
     68 + OnPropertyChanged();
    70 69   }
    71  - #endregion
     70 + }
     71 + #endregion
    72 72   
    73  - #region Constructor, load
    74  - public WebConsoleControl(WebConsoleSessionInfo info)
    75  - {
    76  - InitializeComponent();
    77  - DataContext = this;
     73 + #region Constructor, load
     74 + public WebConsoleControl(WebConsoleSessionInfo info)
     75 + {
     76 + InitializeComponent();
     77 + DataContext = this;
    78 78   
    79  - _sessionInfo = info;
     79 + _sessionInfo = info;
    80 80   
    81  - Browser2.NavigationStarting += Browser2_NavigationStarting;
    82  - Browser2.NavigationCompleted += Browser2_NavigationCompleted;
    83  - Browser2.WebMessageReceived += Browser2_WebMessageReceived;
     81 + Browser2.NavigationStarting += Browser2_NavigationStarting;
     82 + Browser2.NavigationCompleted += Browser2_NavigationCompleted;
     83 + Browser2.WebMessageReceived += Browser2_WebMessageReceived;
    84 84   
    85  - Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
    86  - }
     85 + Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
     86 + }
    87 87   
    88  - private async void UserControl_Loaded(object sender, RoutedEventArgs e)
    89  - {
    90  - // Connect after the control is drawn and only on the first init
    91  - if (_initialized)
    92  - return;
     88 + private async void UserControl_Loaded(object sender, RoutedEventArgs e)
     89 + {
     90 + // Connect after the control is drawn and only on the first init
     91 + if (_initialized)
     92 + return;
    93 93  
    94  - // Set user data folder - Fix #382
    95  - var webView2Environment = await CoreWebView2Environment.CreateAsync(null, GlobalStaticConfiguration.WebConsole_Cache);
    96  - await Browser2.EnsureCoreWebView2Async(webView2Environment);
     94 + // Set user data folder - Fix #382
     95 + var webView2Environment = await CoreWebView2Environment.CreateAsync(null, GlobalStaticConfiguration.WebConsole_Cache);
     96 + await Browser2.EnsureCoreWebView2Async(webView2Environment);
    97 97   
    98  - Connect();
     98 + Connect();
    99 99   
    100  - _initialized = true;
    101  - }
     100 + _initialized = true;
     101 + }
    102 102   
    103  - private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
    104  - {
    105  - CloseTab();
    106  - }
    107  - #endregion
     103 + private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
     104 + {
     105 + CloseTab();
     106 + }
     107 + #endregion
    108 108   
    109  - #region ICommands & Actions
    110  - public ICommand NavigateCommand
    111  - {
    112  - get { return new RelayCommand(p => NavigateAction(), NavigateCommand_CanExecute); }
    113  - }
     109 + #region ICommands & Actions
     110 + public ICommand NavigateCommand
     111 + {
     112 + get { return new RelayCommand(p => NavigateAction(), NavigateCommand_CanExecute); }
     113 + }
    114 114   
    115  - private bool NavigateCommand_CanExecute(object obj)
    116  - {
    117  - return !IsLoading;
    118  - }
     115 + private bool NavigateCommand_CanExecute(object obj)
     116 + {
     117 + return !IsLoading;
     118 + }
    119 119   
    120  - private void NavigateAction()
    121  - {
    122  - Browser2.CoreWebView2.Navigate(Url);
    123  - }
     120 + private void NavigateAction()
     121 + {
     122 + Browser2.CoreWebView2.Navigate(Url);
     123 + }
    124 124   
    125  - public ICommand ReloadCommand
    126  - {
    127  - get { return new RelayCommand(p => ReloadAction(), ReloadCommand_CanExecute); }
    128  - }
     125 + public ICommand ReloadCommand
     126 + {
     127 + get { return new RelayCommand(p => ReloadAction(), ReloadCommand_CanExecute); }
     128 + }
    129 129   
    130  - private bool ReloadCommand_CanExecute(object obj)
    131  - {
    132  - return !IsLoading;
    133  - }
     130 + private bool ReloadCommand_CanExecute(object obj)
     131 + {
     132 + return !IsLoading;
     133 + }
    134 134   
    135  - private void ReloadAction()
    136  - {
    137  - Browser2.Reload();
    138  - }
     135 + private void ReloadAction()
     136 + {
     137 + Browser2.Reload();
     138 + }
    139 139   
    140  - public ICommand GoBackCommand
    141  - {
    142  - get { return new RelayCommand(p => GoBackAction(), GoBackCommand_CanExecute); }
    143  - }
     140 + public ICommand GoBackCommand
     141 + {
     142 + get { return new RelayCommand(p => GoBackAction(), GoBackCommand_CanExecute); }
     143 + }
    144 144   
    145  - private bool GoBackCommand_CanExecute(object obj)
    146  - {
    147  - return !IsLoading && Browser2.CanGoBack;
    148  - }
     145 + private bool GoBackCommand_CanExecute(object obj)
     146 + {
     147 + return !IsLoading && Browser2.CanGoBack;
     148 + }
    149 149   
    150  - private void GoBackAction()
    151  - {
    152  - Browser2.GoBack();
    153  - }
     150 + private void GoBackAction()
     151 + {
     152 + Browser2.GoBack();
     153 + }
    154 154   
    155  - public ICommand GoForwardCommand
    156  - {
    157  - get { return new RelayCommand(p => GoForwardAction(), GoForwardCommand_CanExecute); }
    158  - }
     155 + public ICommand GoForwardCommand
     156 + {
     157 + get { return new RelayCommand(p => GoForwardAction(), GoForwardCommand_CanExecute); }
     158 + }
    159 159   
    160  - private bool GoForwardCommand_CanExecute(object obj)
    161  - {
    162  - return !IsLoading && Browser2.CanGoForward;
    163  - }
     160 + private bool GoForwardCommand_CanExecute(object obj)
     161 + {
     162 + return !IsLoading && Browser2.CanGoForward;
     163 + }
    164 164   
    165  - private void GoForwardAction()
    166  - {
    167  - Browser2.GoForward();
    168  - }
    169  - #endregion
     165 + private void GoForwardAction()
     166 + {
     167 + Browser2.GoForward();
     168 + }
     169 + #endregion
    170 170   
    171  - #region Methods
    172  - private void Connect()
    173  - {
    174  - Browser2.Source = new Uri(_sessionInfo.Url);
    175  - }
     171 + #region Methods
     172 + private void Connect()
     173 + {
     174 + Browser2.Source = new Uri(_sessionInfo.Url);
     175 + }
    176 176   
    177  - public void CloseTab()
    178  - {
     177 + public void CloseTab()
     178 + {
    179 179   
    180  - }
    181  - #endregion
     180 + }
     181 + #endregion
    182 182   
    183  - #region Events
    184  - private void Browser2_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
    185  - {
    186  - if (FirstLoad)
    187  - FirstLoad = false;
     183 + #region Events
     184 + private void Browser2_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
     185 + {
     186 + if (FirstLoad)
     187 + FirstLoad = false;
    188 188   
    189  - IsLoading = false;
    190  - }
     189 + IsLoading = false;
     190 + }
    191 191   
    192  - private void Browser2_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e)
    193  - {
    194  - IsLoading = true;
     192 + private void Browser2_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e)
     193 + {
     194 + IsLoading = true;
    195 195   
    196  - Url = e.Uri.ToString();
    197  - }
     196 + Url = e.Uri.ToString();
     197 + }
    198 198   
    199  - private void Browser2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
    200  - {
    201  - string uri = e.TryGetWebMessageAsString();
    202  - Url = uri;
    203  - }
    204  - #endregion
     199 + private void Browser2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
     200 + {
     201 + string uri = e.TryGetWebMessageAsString();
     202 + Url = uri;
    205 203   }
     204 + #endregion
    206 205  }
    207 206   
  • Source/NETworkManager/MainWindow.xaml.cs
    Diff is too large to be displayed.
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/StatusWindow.xaml.cs
    skipped 5 lines
    6 6  using System.Windows.Forms;
    7 7  using System.Windows.Input;
    8 8   
    9  -namespace NETworkManager
     9 +namespace NETworkManager;
     10 + 
     11 +public partial class StatusWindow : MetroWindow, INotifyPropertyChanged
    10 12  {
    11  - public partial class StatusWindow : MetroWindow, INotifyPropertyChanged
     13 + #region PropertyChangedEventHandler
     14 + public event PropertyChangedEventHandler PropertyChanged;
     15 + 
     16 + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    12 17   {
    13  - #region PropertyChangedEventHandler
    14  - public event PropertyChangedEventHandler PropertyChanged;
     18 + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     19 + }
     20 + #endregion
    15 21   
    16  - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    17  - {
    18  - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    19  - }
    20  - #endregion
     22 + #region Variables
     23 + private MainWindow _mainWindow;
     24 + private NetworkConnectionView _networkConnectionView;
     25 + #endregion
    21 26   
    22  - #region Variables
    23  - private MainWindow _mainWindow;
    24  - private NetworkConnectionView _networkConnectionView;
    25  - #endregion
     27 + #region Constructor
     28 + public StatusWindow(MainWindow mainWindow)
     29 + {
     30 + InitializeComponent();
     31 + DataContext = this;
    26 32   
    27  - #region Constructor
    28  - public StatusWindow(MainWindow mainWindow)
    29  - {
    30  - InitializeComponent();
    31  - DataContext = this;
     33 + _mainWindow = mainWindow;
    32 34   
    33  - _mainWindow = mainWindow;
     35 + _networkConnectionView = new NetworkConnectionView();
     36 + ContentControlNetworkConnection.Content = _networkConnectionView;
     37 + }
     38 + #endregion
    34 39   
    35  - _networkConnectionView = new NetworkConnectionView();
    36  - ContentControlNetworkConnection.Content = _networkConnectionView;
    37  - }
    38  - #endregion
     40 + #region ICommands & Actions
     41 + public ICommand ReloadCommand => new RelayCommand(p => ReloadAction());
    39 42   
    40  - #region ICommands & Actions
    41  - public ICommand ReloadCommand => new RelayCommand(p => ReloadAction());
     43 + private void ReloadAction()
     44 + {
     45 + Reload();
     46 + }
    42 47   
    43  - private void ReloadAction()
    44  - {
    45  - Reload();
    46  - }
     48 + public ICommand ShowMainWindowCommand => new RelayCommand(p => ShowMainWindowAction());
    47 49   
    48  - public ICommand ShowMainWindowCommand => new RelayCommand(p => ShowMainWindowAction());
     50 + private void ShowMainWindowAction()
     51 + {
     52 + Hide();
    49 53   
    50  - private void ShowMainWindowAction()
    51  - {
    52  - Hide();
     54 + if (_mainWindow.ShowWindowCommand.CanExecute(null))
     55 + _mainWindow.ShowWindowCommand.Execute(null);
     56 + }
    53 57   
    54  - if (_mainWindow.ShowWindowCommand.CanExecute(null))
    55  - _mainWindow.ShowWindowCommand.Execute(null);
    56  - }
     58 + public ICommand CloseCommand => new RelayCommand(p => CloseAction());
    57 59   
    58  - public ICommand CloseCommand => new RelayCommand(p => CloseAction());
     60 + private void CloseAction()
     61 + {
     62 + Hide();
     63 + }
    59 64   
    60  - private void CloseAction()
    61  - {
    62  - Hide();
    63  - }
     65 + #endregion
    64 66   
    65  - #endregion
     67 + #region Methods
     68 + private void Reload()
     69 + {
     70 + _networkConnectionView.Reload();
     71 + }
    66 72   
    67  - #region Methods
    68  - private void Reload()
    69  - {
    70  - _networkConnectionView.Reload();
    71  - }
     73 + /// <summary>
     74 + /// Show the window on the screen.
     75 + /// </summary>
     76 + /// <param name="activate">Focus the window (will automatically hide if the focus is lost).</param>
     77 + public void ShowWindow(bool activate)
     78 + {
     79 + // Show on primary screen in left/bottom corner
     80 + // ToDo: User setting...
     81 + Left = Screen.PrimaryScreen.WorkingArea.Right - Width - 10;
     82 + Top = Screen.PrimaryScreen.WorkingArea.Bottom - Height - 10;
    72 83   
    73  - /// <summary>
    74  - /// Show the window on the screen.
    75  - /// </summary>
    76  - /// <param name="activate">Focus the window (will automatically hide if the focus is lost).</param>
    77  - public void ShowWindow(bool activate)
    78  - {
    79  - // Show on primary screen in left/bottom corner
    80  - // ToDo: User setting...
    81  - Left = Screen.PrimaryScreen.WorkingArea.Right - Width - 10;
    82  - Top = Screen.PrimaryScreen.WorkingArea.Bottom - Height - 10;
     84 + Show();
    83 85   
    84  - Show();
     86 + if (activate)
     87 + Activate();
    85 88   
    86  - if (activate)
    87  - Activate();
     89 + Topmost = true;
     90 + }
     91 + #endregion
    88 92   
    89  - Topmost = true;
    90  - }
    91  - #endregion
     93 + #region Events
     94 + private void MetroWindow_Deactivated(object sender, System.EventArgs e)
     95 + {
     96 + Hide();
     97 + }
    92 98   
    93  - #region Events
    94  - private void MetroWindow_Deactivated(object sender, System.EventArgs e)
    95  - {
    96  - Hide();
    97  - }
    98  - 
    99  - private void MetroWindow_Closing(object sender, CancelEventArgs e)
    100  - {
    101  - e.Cancel = true;
     99 + private void MetroWindow_Closing(object sender, CancelEventArgs e)
     100 + {
     101 + e.Cancel = true;
    102 102   
    103  - Hide();
    104  - }
     103 + Hide();
     104 + }
    105 105   
    106  - #endregion
     106 + #endregion
    107 107   
    108 108   
    109  - }
    110 109  }
    111 110   
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/ARPTableAddEntryViewModel.cs
    skipped 1 lines
    2 2  using System;
    3 3  using System.Windows.Input;
    4 4   
    5  -namespace NETworkManager.ViewModels
     5 +namespace NETworkManager.ViewModels;
     6 + 
     7 +public class ArpTableAddEntryViewModel : ViewModelBase
    6 8  {
    7  - public class ArpTableAddEntryViewModel : ViewModelBase
    8  - {
    9  - public ICommand AddCommand { get; }
     9 + public ICommand AddCommand { get; }
    10 10   
    11  - public ICommand CancelCommand { get; }
     11 + public ICommand CancelCommand { get; }
    12 12   
    13  - private string _ipAddress;
    14  - public string IPAddress
     13 + private string _ipAddress;
     14 + public string IPAddress
     15 + {
     16 + get => _ipAddress;
     17 + set
    15 18   {
    16  - get => _ipAddress;
    17  - set
    18  - {
    19  - if (value == _ipAddress)
    20  - return;
     19 + if (value == _ipAddress)
     20 + return;
    21 21   
    22  - _ipAddress = value;
    23  - OnPropertyChanged();
    24  - }
     22 + _ipAddress = value;
     23 + OnPropertyChanged();
    25 24   }
     25 + }
    26 26   
    27  - private string _macAddress;
    28  - public string MACAddress
     27 + private string _macAddress;
     28 + public string MACAddress
     29 + {
     30 + get => _macAddress;
     31 + set
    29 32   {
    30  - get => _macAddress;
    31  - set
    32  - {
    33  - if (value == _macAddress)
    34  - return;
     33 + if (value == _macAddress)
     34 + return;
    35 35   
    36  - _macAddress = value;
    37  - OnPropertyChanged();
    38  - }
     36 + _macAddress = value;
     37 + OnPropertyChanged();
    39 38   }
     39 + }
    40 40   
    41  - public ArpTableAddEntryViewModel(Action<ArpTableAddEntryViewModel> addCommand, Action<ArpTableAddEntryViewModel> cancelHandler)
    42  - {
    43  - AddCommand = new RelayCommand(p => addCommand(this));
    44  - CancelCommand = new RelayCommand(p => cancelHandler(this));
    45  - }
     41 + public ArpTableAddEntryViewModel(Action<ArpTableAddEntryViewModel> addCommand, Action<ArpTableAddEntryViewModel> cancelHandler)
     42 + {
     43 + AddCommand = new RelayCommand(p => addCommand(this));
     44 + CancelCommand = new RelayCommand(p => cancelHandler(this));
    46 45   }
    47 46  }
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/ARPTableViewModel.cs
    skipped 15 lines
    16 16  using NETworkManager.Models.Export;
    17 17  using System.Threading.Tasks;
    18 18   
    19  -namespace NETworkManager.ViewModels
     19 +namespace NETworkManager.ViewModels;
     20 + 
     21 +public class ARPTableViewModel : ViewModelBase
    20 22  {
    21  - public class ARPTableViewModel : ViewModelBase
    22  - {
    23  - #region Variables
    24  - private readonly IDialogCoordinator _dialogCoordinator;
     23 + #region Variables
     24 + private readonly IDialogCoordinator _dialogCoordinator;
    25 25   
    26  - private readonly bool _isLoading;
    27  - private readonly DispatcherTimer _autoRefreshTimer = new DispatcherTimer();
    28  - private bool _isTimerPaused;
     26 + private readonly bool _isLoading;
     27 + private readonly DispatcherTimer _autoRefreshTimer = new DispatcherTimer();
     28 + private bool _isTimerPaused;
    29 29   
    30  - private string _search;
    31  - public string Search
     30 + private string _search;
     31 + public string Search
     32 + {
     33 + get => _search;
     34 + set
    32 35   {
    33  - get => _search;
    34  - set
    35  - {
    36  - if (value == _search)
    37  - return;
     36 + if (value == _search)
     37 + return;
    38 38   
    39  - _search = value;
     39 + _search = value;
    40 40   
    41  - ARPInfoResultsView.Refresh();
     41 + ARPInfoResultsView.Refresh();
    42 42   
    43  - OnPropertyChanged();
    44  - }
     43 + OnPropertyChanged();
    45 44   }
     45 + }
    46 46   
    47  - private ObservableCollection<ARPInfo> _arpInfoResults = new ObservableCollection<ARPInfo>();
    48  - public ObservableCollection<ARPInfo> ARPInfoResults
     47 + private ObservableCollection<ARPInfo> _arpInfoResults = new ObservableCollection<ARPInfo>();
     48 + public ObservableCollection<ARPInfo> ARPInfoResults
     49 + {
     50 + get => _arpInfoResults;
     51 + set
    49 52   {
    50  - get => _arpInfoResults;
    51  - set
    52  - {
    53  - if (value == _arpInfoResults)
    54  - return;
     53 + if (value == _arpInfoResults)
     54 + return;
    55 55   
    56  - _arpInfoResults = value;
    57  - OnPropertyChanged();
    58  - }
     56 + _arpInfoResults = value;
     57 + OnPropertyChanged();
    59 58   }
     59 + }
    60 60   
    61  - public ICollectionView ARPInfoResultsView { get; }
     61 + public ICollectionView ARPInfoResultsView { get; }
    62 62   
    63  - private ARPInfo _selectedARPInfo;
    64  - public ARPInfo SelectedARPInfo
     63 + private ARPInfo _selectedARPInfo;
     64 + public ARPInfo SelectedARPInfo
     65 + {
     66 + get => _selectedARPInfo;
     67 + set
    65 68   {
    66  - get => _selectedARPInfo;
    67  - set
    68  - {
    69  - if (value == _selectedARPInfo)
    70  - return;
     69 + if (value == _selectedARPInfo)
     70 + return;
    71 71   
    72  - _selectedARPInfo = value;
    73  - OnPropertyChanged();
    74  - }
     72 + _selectedARPInfo = value;
     73 + OnPropertyChanged();
    75 74   }
     75 + }
    76 76   
    77  - private IList _selectedARPInfos = new ArrayList();
    78  - public IList SelectedARPInfos
     77 + private IList _selectedARPInfos = new ArrayList();
     78 + public IList SelectedARPInfos
     79 + {
     80 + get => _selectedARPInfos;
     81 + set
    79 82   {
    80  - get => _selectedARPInfos;
    81  - set
    82  - {
    83  - if (Equals(value, _selectedARPInfos))
    84  - return;
     83 + if (Equals(value, _selectedARPInfos))
     84 + return;
    85 85   
    86  - _selectedARPInfos = value;
    87  - OnPropertyChanged();
    88  - }
     86 + _selectedARPInfos = value;
     87 + OnPropertyChanged();
    89 88   }
     89 + }
    90 90   
    91  - private bool _autoRefresh;
    92  - public bool AutoRefresh
     91 + private bool _autoRefresh;
     92 + public bool AutoRefresh
     93 + {
     94 + get => _autoRefresh;
     95 + set
    93 96   {
    94  - get => _autoRefresh;
    95  - set
    96  - {
    97  - if (value == _autoRefresh)
    98  - return;
    99  - 
    100  - if (!_isLoading)
    101  - SettingsManager.Current.ARPTable_AutoRefresh = value;
     97 + if (value == _autoRefresh)
     98 + return;
    102 99   
    103  - _autoRefresh = value;
     100 + if (!_isLoading)
     101 + SettingsManager.Current.ARPTable_AutoRefresh = value;
    104 102   
    105  - // Start timer to refresh automatically
    106  - if (!_isLoading)
    107  - {
    108  - if (value)
    109  - StartAutoRefreshTimer();
    110  - else
    111  - StopAutoRefreshTimer();
    112  - }
     103 + _autoRefresh = value;
    113 104   
    114  - OnPropertyChanged();
     105 + // Start timer to refresh automatically
     106 + if (!_isLoading)
     107 + {
     108 + if (value)
     109 + StartAutoRefreshTimer();
     110 + else
     111 + StopAutoRefreshTimer();
    115 112   }
     113 + 
     114 + OnPropertyChanged();
    116 115   }
     116 + }
    117 117   
    118  - public ICollectionView AutoRefreshTimes { get; }
     118 + public ICollectionView AutoRefreshTimes { get; }
    119 119   
    120  - private AutoRefreshTimeInfo _selectedAutoRefreshTime;
    121  - public AutoRefreshTimeInfo SelectedAutoRefreshTime
     120 + private AutoRefreshTimeInfo _selectedAutoRefreshTime;
     121 + public AutoRefreshTimeInfo SelectedAutoRefreshTime
     122 + {
     123 + get => _selectedAutoRefreshTime;
     124 + set
    122 125   {
    123  - get => _selectedAutoRefreshTime;
    124  - set
    125  - {
    126  - if (value == _selectedAutoRefreshTime)
    127  - return;
     126 + if (value == _selectedAutoRefreshTime)
     127 + return;
    128 128   
    129  - if (!_isLoading)
    130  - SettingsManager.Current.ARPTable_AutoRefreshTime = value;
     129 + if (!_isLoading)
     130 + SettingsManager.Current.ARPTable_AutoRefreshTime = value;
    131 131   
    132  - _selectedAutoRefreshTime = value;
     132 + _selectedAutoRefreshTime = value;
    133 133   
    134  - if (AutoRefresh)
    135  - ChangeAutoRefreshTimerInterval(AutoRefreshTime.CalculateTimeSpan(value));
     134 + if (AutoRefresh)
     135 + ChangeAutoRefreshTimerInterval(AutoRefreshTime.CalculateTimeSpan(value));
    136 136   
    137  - OnPropertyChanged();
    138  - }
     137 + OnPropertyChanged();
    139 138   }
     139 + }
    140 140   
    141  - private bool _isRefreshing;
    142  - public bool IsRefreshing
     141 + private bool _isRefreshing;
     142 + public bool IsRefreshing
     143 + {
     144 + get => _isRefreshing;
     145 + set
    143 146   {
    144  - get => _isRefreshing;
    145  - set
    146  - {
    147  - if (value == _isRefreshing)
    148  - return;
     147 + if (value == _isRefreshing)
     148 + return;
    149 149   
    150  - _isRefreshing = value;
    151  - OnPropertyChanged();
    152  - }
     150 + _isRefreshing = value;
     151 + OnPropertyChanged();
    153 152   }
     153 + }
    154 154   
    155  - private bool _isStatusMessageDisplayed;
    156  - public bool IsStatusMessageDisplayed
     155 + private bool _isStatusMessageDisplayed;
     156 + public bool IsStatusMessageDisplayed
     157 + {
     158 + get => _isStatusMessageDisplayed;
     159 + set
    157 160   {
    158  - get => _isStatusMessageDisplayed;
    159  - set
    160  - {
    161  - if (value == _isStatusMessageDisplayed)
    162  - return;
     161 + if (value == _isStatusMessageDisplayed)
     162 + return;
    163 163   
    164  - _isStatusMessageDisplayed = value;
    165  - OnPropertyChanged();
    166  - }
     164 + _isStatusMessageDisplayed = value;
     165 + OnPropertyChanged();
    167 166   }
     167 + }
    168 168   
    169  - private string _statusMessage;
    170  - public string StatusMessage
     169 + private string _statusMessage;
     170 + public string StatusMessage
     171 + {
     172 + get => _statusMessage;
     173 + set
    171 174   {
    172  - get => _statusMessage;
    173  - set
    174  - {
    175  - if (value == _statusMessage)
    176  - return;
     175 + if (value == _statusMessage)
     176 + return;
    177 177   
    178  - _statusMessage = value;
    179  - OnPropertyChanged();
    180  - }
     178 + _statusMessage = value;
     179 + OnPropertyChanged();
    181 180   }
    182  - #endregion
     181 + }
     182 + #endregion
    183 183   
    184  - #region Contructor, load settings
    185  - public ARPTableViewModel(IDialogCoordinator instance)
     184 + #region Contructor, load settings
     185 + public ARPTableViewModel(IDialogCoordinator instance)
     186 + {
     187 + _isLoading = true;
     188 + _dialogCoordinator = instance;
     189 + 
     190 + // Result view + search
     191 + ARPInfoResultsView = CollectionViewSource.GetDefaultView(ARPInfoResults);
     192 + ARPInfoResultsView.SortDescriptions.Add(new SortDescription(nameof(ARPInfo.IPAddressInt32), ListSortDirection.Ascending));
     193 + ARPInfoResultsView.Filter = o =>
    186 194   {
    187  - _isLoading = true;
    188  - _dialogCoordinator = instance;
     195 + if (!(o is ARPInfo info))
     196 + return false;
     197 + 
     198 + if (string.IsNullOrEmpty(Search))
     199 + return true;
     200 + 
     201 + // Search by IPAddress and MACAddress
     202 + return info.IPAddress.ToString().IndexOf(Search, StringComparison.OrdinalIgnoreCase) > -1 || info.MACAddress.ToString().IndexOf(Search, StringComparison.OrdinalIgnoreCase) > -1 || (info.IsMulticast ? Localization.Resources.Strings.Yes : Localization.Resources.Strings.No).IndexOf(Search, StringComparison.OrdinalIgnoreCase) > -1;
     203 + };
     204 + 
     205 + AutoRefreshTimes = CollectionViewSource.GetDefaultView(AutoRefreshTime.GetDefaults);
     206 + SelectedAutoRefreshTime = AutoRefreshTimes.SourceCollection.Cast<AutoRefreshTimeInfo>().FirstOrDefault(x => (x.Value == SettingsManager.Current.ARPTable_AutoRefreshTime.Value && x.TimeUnit == SettingsManager.Current.ARPTable_AutoRefreshTime.TimeUnit));
     207 + 
     208 + _autoRefreshTimer.Tick += AutoRefreshTimer_Tick;
     209 + 
     210 + LoadSettings();
     211 + 
     212 + _isLoading = false;
     213 + 
     214 + Run();
     215 + }
    189 216   
    190  - // Result view + search
    191  - ARPInfoResultsView = CollectionViewSource.GetDefaultView(ARPInfoResults);
    192  - ARPInfoResultsView.SortDescriptions.Add(new SortDescription(nameof(ARPInfo.IPAddressInt32), ListSortDirection.Ascending));
    193  - ARPInfoResultsView.Filter = o =>
    194  - {
    195  - if (!(o is ARPInfo info))
    196  - return false;
     217 + private async Task Run()
     218 + {
     219 + await Refresh();
    197 220   
    198  - if (string.IsNullOrEmpty(Search))
    199  - return true;
     221 + if (AutoRefresh)
     222 + StartAutoRefreshTimer();
     223 + }
    200 224   
    201  - // Search by IPAddress and MACAddress
    202  - return info.IPAddress.ToString().IndexOf(Search, StringComparison.OrdinalIgnoreCase) > -1 || info.MACAddress.ToString().IndexOf(Search, StringComparison.OrdinalIgnoreCase) > -1 || (info.IsMulticast ? Localization.Resources.Strings.Yes : Localization.Resources.Strings.No).IndexOf(Search, StringComparison.OrdinalIgnoreCase) > -1;
    203  - };
     225 + private void LoadSettings()
     226 + {
     227 + AutoRefresh = SettingsManager.Current.ARPTable_AutoRefresh;
     228 + }
     229 + #endregion
    204 230   
    205  - AutoRefreshTimes = CollectionViewSource.GetDefaultView(AutoRefreshTime.GetDefaults);
    206  - SelectedAutoRefreshTime = AutoRefreshTimes.SourceCollection.Cast<AutoRefreshTimeInfo>().FirstOrDefault(x => (x.Value == SettingsManager.Current.ARPTable_AutoRefreshTime.Value && x.TimeUnit == SettingsManager.Current.ARPTable_AutoRefreshTime.TimeUnit));
     231 + #region ICommands & Actions
     232 + public ICommand RefreshCommand => new RelayCommand(p => RefreshAction(), Refresh_CanExecute);
    207 233   
    208  - _autoRefreshTimer.Tick += AutoRefreshTimer_Tick;
     234 + private bool Refresh_CanExecute(object paramter)
     235 + {
     236 + return Application.Current.MainWindow != null && !((MetroWindow)Application.Current.MainWindow).IsAnyDialogOpen;
     237 + }
    209 238   
    210  - LoadSettings();
     239 + private async Task RefreshAction()
     240 + {
     241 + IsStatusMessageDisplayed = false;
    211 242   
    212  - _isLoading = false;
     243 + await Refresh();
     244 + }
    213 245   
    214  - Run();
    215  - }
     246 + public ICommand DeleteTableCommand => new RelayCommand(p => DeleteTableAction(), DeleteTable_CanExecute);
    216 247   
    217  - private async Task Run()
    218  - {
    219  - await Refresh();
     248 + private bool DeleteTable_CanExecute(object paramter)
     249 + {
     250 + return Application.Current.MainWindow != null && !((MetroWindow)Application.Current.MainWindow).IsAnyDialogOpen;
     251 + }
    220 252   
    221  - if (AutoRefresh)
    222  - StartAutoRefreshTimer();
    223  - }
     253 + private async Task DeleteTableAction()
     254 + {
     255 + IsStatusMessageDisplayed = false;
    224 256   
    225  - private void LoadSettings()
     257 + try
    226 258   {
    227  - AutoRefresh = SettingsManager.Current.ARPTable_AutoRefresh;
    228  - }
    229  - #endregion
     259 + var arpTable = new ARP();
     260 + 
     261 + arpTable.UserHasCanceled += ArpTable_UserHasCanceled;
    230 262   
    231  - #region ICommands & Actions
    232  - public ICommand RefreshCommand => new RelayCommand(p => RefreshAction(), Refresh_CanExecute);
     263 + await arpTable.DeleteTableAsync();
    233 264   
    234  - private bool Refresh_CanExecute(object paramter)
     265 + await Refresh();
     266 + }
     267 + catch (Exception ex)
    235 268   {
    236  - return Application.Current.MainWindow != null && !((MetroWindow)Application.Current.MainWindow).IsAnyDialogOpen;
     269 + StatusMessage = ex.Message;
     270 + IsStatusMessageDisplayed = true;
    237 271   }
     272 + }
    238 273   
    239  - private async Task RefreshAction()
    240  - {
    241  - IsStatusMessageDisplayed = false;
     274 + public ICommand DeleteEntryCommand => new RelayCommand(p => DeleteEntryAction(), DeleteEntry_CanExecute);
    242 275   
    243  - await Refresh();
    244  - }
     276 + private bool DeleteEntry_CanExecute(object paramter) => Application.Current.MainWindow != null && !((MetroWindow)Application.Current.MainWindow).IsAnyDialogOpen;
    245 277   
    246  - public ICommand DeleteTableCommand => new RelayCommand(p => DeleteTableAction(), DeleteTable_CanExecute);
     278 + private async Task DeleteEntryAction()
     279 + {
     280 + IsStatusMessageDisplayed = false;
    247 281   
    248  - private bool DeleteTable_CanExecute(object paramter)
     282 + try
    249 283   {
    250  - return Application.Current.MainWindow != null && !((MetroWindow)Application.Current.MainWindow).IsAnyDialogOpen;
    251  - }
     284 + var arpTable = new ARP();
    252 285   
    253  - private async Task DeleteTableAction()
    254  - {
    255  - IsStatusMessageDisplayed = false;
     286 + arpTable.UserHasCanceled += ArpTable_UserHasCanceled;
    256 287   
    257  - try
    258  - {
    259  - var arpTable = new ARP();
     288 + await arpTable.DeleteEntryAsync(SelectedARPInfo.IPAddress.ToString());
    260 289   
    261  - arpTable.UserHasCanceled += ArpTable_UserHasCanceled;
     290 + await Refresh();
     291 + }
     292 + catch (Exception ex)
     293 + {
     294 + StatusMessage = ex.Message;
     295 + IsStatusMessageDisplayed = true;
     296 + }
     297 + }
    262 298   
    263  - await arpTable.DeleteTableAsync();
     299 + public ICommand AddEntryCommand => new RelayCommand(p => AddEntryAction(), AddEntry_CanExecute);
    264 300   
    265  - await Refresh();
    266  - }
    267  - catch (Exception ex)
    268  - {
    269  - StatusMessage = ex.Message;
    270  - IsStatusMessageDisplayed = true;
    271  - }
    272  - }
     301 + private bool AddEntry_CanExecute(object paramter) => Application.Current.MainWindow != null && !((MetroWindow)Application.Current.MainWindow).IsAnyDialogOpen;
    273 302   
    274  - public ICommand DeleteEntryCommand => new RelayCommand(p => DeleteEntryAction(), DeleteEntry_CanExecute);
     303 + private async Task AddEntryAction()
     304 + {
     305 + IsStatusMessageDisplayed = false;
    275 306   
    276  - private bool DeleteEntry_CanExecute(object paramter) => Application.Current.MainWindow != null && !((MetroWindow)Application.Current.MainWindow).IsAnyDialogOpen;
     307 + var customDialog = new CustomDialog
     308 + {
     309 + Title = Localization.Resources.Strings.AddEntry
     310 + };
    277 311   
    278  - private async Task DeleteEntryAction()
     312 + var arpTableAddEntryViewModel = new ArpTableAddEntryViewModel(async instance =>
    279 313   {
    280  - IsStatusMessageDisplayed = false;
     314 + await _dialogCoordinator.HideMetroDialogAsync(this, customDialog);
    281 315   
    282 316   try
    283 317   {
    skipped 1 lines
    285 319   
    286 320   arpTable.UserHasCanceled += ArpTable_UserHasCanceled;
    287 321   
    288  - await arpTable.DeleteEntryAsync(SelectedARPInfo.IPAddress.ToString());
     322 + await arpTable.AddEntryAsync(instance.IPAddress, MACAddressHelper.Format(instance.MACAddress, "-"));
    289 323   
    290 324   await Refresh();
    291 325   }
    skipped 2 lines
    294 328   StatusMessage = ex.Message;
    295 329   IsStatusMessageDisplayed = true;
    296 330   }
    297  - }
     331 + }, instance =>
     332 + {
     333 + _dialogCoordinator.HideMetroDialogAsync(this, customDialog);
     334 + });
    298 335   
    299  - public ICommand AddEntryCommand => new RelayCommand(p => AddEntryAction(), AddEntry_CanExecute);
    300  - 
    301  - private bool AddEntry_CanExecute(object paramter) => Application.Current.MainWindow != null && !((MetroWindow)Application.Current.MainWindow).IsAnyDialogOpen;
    302  - 
    303  - private async Task AddEntryAction()
     336 + customDialog.Content = new ARPTableAddEntryDialog
    304 337   {
    305  - IsStatusMessageDisplayed = false;
     338 + DataContext = arpTableAddEntryViewModel
     339 + };
    306 340   
    307  - var customDialog = new CustomDialog
    308  - {
    309  - Title = Localization.Resources.Strings.AddEntry
    310  - };
     341 + await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog);
     342 + }
    311 343   
    312  - var arpTableAddEntryViewModel = new ArpTableAddEntryViewModel(async instance =>
    313  - {
    314  - await _dialogCoordinator.HideMetroDialogAsync(this, customDialog);
     344 + public ICommand CopySelectedIPAddressCommand => new RelayCommand(p => CopySelectedIPAddressAction());
    315 345   
    316  - try
    317  - {
    318  - var arpTable = new ARP();
     346 + private void CopySelectedIPAddressAction()
     347 + {
     348 + ClipboardHelper.SetClipboard(SelectedARPInfo.IPAddress.ToString());
     349 + }
    319 350   
    320  - arpTable.UserHasCanceled += ArpTable_UserHasCanceled;
     351 + public ICommand CopySelectedMACAddressCommand => new RelayCommand(p => CopySelectedMACAddressAction());
    321 352   
    322  - await arpTable.AddEntryAsync(instance.IPAddress, MACAddressHelper.Format(instance.MACAddress, "-"));
     353 + private void CopySelectedMACAddressAction()
     354 + {
     355 + ClipboardHelper.SetClipboard(MACAddressHelper.GetDefaultFormat(SelectedARPInfo.MACAddress.ToString()));
     356 + }
    323 357   
    324  - await Refresh();
    325  - }
    326  - catch (Exception ex)
    327  - {
    328  - StatusMessage = ex.Message;
    329  - IsStatusMessageDisplayed = true;
    330  - }
    331  - }, instance =>
    332  - {
    333  - _dialogCoordinator.HideMetroDialogAsync(this, customDialog);
    334  - });
     358 + public ICommand CopySelectedMulticastCommand => new RelayCommand(p => CopySelectedMulticastAction());
    335 359   
    336  - customDialog.Content = new ARPTableAddEntryDialog
    337  - {
    338  - DataContext = arpTableAddEntryViewModel
    339  - };
    340  - 
    341  - await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog);
    342  - }
    343  - 
    344  - public ICommand CopySelectedIPAddressCommand => new RelayCommand(p => CopySelectedIPAddressAction());
    345  - 
    346  - private void CopySelectedIPAddressAction()
    347  - {
    348  - ClipboardHelper.SetClipboard(SelectedARPInfo.IPAddress.ToString());
    349  - }
     360 + private void CopySelectedMulticastAction()
     361 + {
     362 + ClipboardHelper.SetClipboard(SelectedARPInfo.IsMulticast ? Localization.Resources.Strings.Yes : Localization.Resources.Strings.No);
     363 + }
    350 364   
    351  - public ICommand CopySelectedMACAddressCommand => new RelayCommand(p => CopySelectedMACAddressAction());
     365 + public ICommand ExportCommand => new RelayCommand(p => ExportAction());
    352 366   
    353  - private void CopySelectedMACAddressAction()
     367 + private async Task ExportAction()
     368 + {
     369 + var customDialog = new CustomDialog
    354 370   {
    355  - ClipboardHelper.SetClipboard(MACAddressHelper.GetDefaultFormat(SelectedARPInfo.MACAddress.ToString()));
    356  - }
    357  - 
    358  - public ICommand CopySelectedMulticastCommand => new RelayCommand(p => CopySelectedMulticastAction());
     371 + Title = Localization.Resources.Strings.Export
     372 + };
    359 373   
    360  - private void CopySelectedMulticastAction()
     374 + var exportViewModel = new ExportViewModel(async instance =>
    361 375   {
    362  - ClipboardHelper.SetClipboard(SelectedARPInfo.IsMulticast ? Localization.Resources.Strings.Yes : Localization.Resources.Strings.No);
    363  - }
    364  - 
    365  - public ICommand ExportCommand => new RelayCommand(p => ExportAction());
     376 + await _dialogCoordinator.HideMetroDialogAsync(this, customDialog);
    366 377   
    367  - private async Task ExportAction()
    368  - {
    369  - var customDialog = new CustomDialog
     378 + try
    370 379   {
    371  - Title = Localization.Resources.Strings.Export
    372  - };
    373  - 
    374  - var exportViewModel = new ExportViewModel(async instance =>
     380 + ExportManager.Export(instance.FilePath, instance.FileType, instance.ExportAll ? ARPInfoResults : new ObservableCollection<ARPInfo>(SelectedARPInfos.Cast<ARPInfo>().ToArray()));
     381 + }
     382 + catch (Exception ex)
    375 383   {
    376  - await _dialogCoordinator.HideMetroDialogAsync(this, customDialog);
     384 + var settings = AppearanceManager.MetroDialog;
     385 + settings.AffirmativeButtonText = Localization.Resources.Strings.OK;
    377 386   
    378  - try
    379  - {
    380  - ExportManager.Export(instance.FilePath, instance.FileType, instance.ExportAll ? ARPInfoResults : new ObservableCollection<ARPInfo>(SelectedARPInfos.Cast<ARPInfo>().ToArray()));
    381  - }
    382  - catch (Exception ex)
    383  - {
    384  - var settings = AppearanceManager.MetroDialog;
    385  - settings.AffirmativeButtonText = Localization.Resources.Strings.OK;
     387 + await _dialogCoordinator.ShowMessageAsync(this, Localization.Resources.Strings.Error, Localization.Resources.Strings.AnErrorOccurredWhileExportingTheData + Environment.NewLine + Environment.NewLine + ex.Message, MessageDialogStyle.Affirmative, settings);
     388 + }
    386 389   
    387  - await _dialogCoordinator.ShowMessageAsync(this, Localization.Resources.Strings.Error, Localization.Resources.Strings.AnErrorOccurredWhileExportingTheData + Environment.NewLine + Environment.NewLine + ex.Message, MessageDialogStyle.Affirmative, settings);
    388  - }
     390 + SettingsManager.Current.ARPTable_ExportFileType = instance.FileType;
     391 + SettingsManager.Current.ARPTable_ExportFilePath = instance.FilePath;
     392 + }, instance => { _dialogCoordinator.HideMetroDialogAsync(this, customDialog); }, new ExportManager.ExportFileType[] { ExportManager.ExportFileType.CSV, ExportManager.ExportFileType.XML, ExportManager.ExportFileType.JSON }, true, SettingsManager.Current.ARPTable_ExportFileType, SettingsManager.Current.ARPTable_ExportFilePath);
    389 393   
    390  - SettingsManager.Current.ARPTable_ExportFileType = instance.FileType;
    391  - SettingsManager.Current.ARPTable_ExportFilePath = instance.FilePath;
    392  - }, instance => { _dialogCoordinator.HideMetroDialogAsync(this, customDialog); }, new ExportManager.ExportFileType[] { ExportManager.ExportFileType.CSV, ExportManager.ExportFileType.XML, ExportManager.ExportFileType.JSON }, true, SettingsManager.Current.ARPTable_ExportFileType, SettingsManager.Current.ARPTable_ExportFilePath);
     394 + customDialog.Content = new ExportDialog
     395 + {
     396 + DataContext = exportViewModel
     397 + };
    393 398   
    394  - customDialog.Content = new ExportDialog
    395  - {
    396  - DataContext = exportViewModel
    397  - };
     399 + await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog);
     400 + }
     401 + #endregion
    398 402   
    399  - await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog);
    400  - }
    401  - #endregion
     403 + #region Methods
     404 + private async Task Refresh()
     405 + {
     406 + IsRefreshing = true;
    402 407   
    403  - #region Methods
    404  - private async Task Refresh()
    405  - {
    406  - IsRefreshing = true;
     408 + ARPInfoResults.Clear();
    407 409   
    408  - ARPInfoResults.Clear();
     410 + (await ARP.GetTableAsync()).ForEach(x => ARPInfoResults.Add(x));
    409 411   
    410  - (await ARP.GetTableAsync()).ForEach(x => ARPInfoResults.Add(x));
     412 + IsRefreshing = false;
     413 + }
    411 414   
    412  - IsRefreshing = false;
    413  - }
     415 + private void ChangeAutoRefreshTimerInterval(TimeSpan timeSpan)
     416 + {
     417 + _autoRefreshTimer.Interval = timeSpan;
     418 + }
    414 419   
    415  - private void ChangeAutoRefreshTimerInterval(TimeSpan timeSpan)
    416  - {
    417  - _autoRefreshTimer.Interval = timeSpan;
    418  - }
     420 + private void StartAutoRefreshTimer()
     421 + {
     422 + ChangeAutoRefreshTimerInterval(AutoRefreshTime.CalculateTimeSpan(SelectedAutoRefreshTime));
    419 423   
    420  - private void StartAutoRefreshTimer()
    421  - {
    422  - ChangeAutoRefreshTimerInterval(AutoRefreshTime.CalculateTimeSpan(SelectedAutoRefreshTime));
     424 + _autoRefreshTimer.Start();
     425 + }
    423 426   
    424  - _autoRefreshTimer.Start();
    425  - }
     427 + private void StopAutoRefreshTimer()
     428 + {
     429 + _autoRefreshTimer.Stop();
     430 + }
    426 431   
    427  - private void StopAutoRefreshTimer()
    428  - {
    429  - _autoRefreshTimer.Stop();
    430  - }
     432 + private void PauseAutoRefreshTimer()
     433 + {
     434 + if (!_autoRefreshTimer.IsEnabled)
     435 + return;
    431 436   
    432  - private void PauseAutoRefreshTimer()
    433  - {
    434  - if (!_autoRefreshTimer.IsEnabled)
    435  - return;
     437 + _autoRefreshTimer.Stop();
    436 438   
    437  - _autoRefreshTimer.Stop();
     439 + _isTimerPaused = true;
     440 + }
    438 441   
    439  - _isTimerPaused = true;
    440  - }
     442 + private void ResumeAutoRefreshTimer()
     443 + {
     444 + if (!_isTimerPaused)
     445 + return;
    441 446   
    442  - private void ResumeAutoRefreshTimer()
    443  - {
    444  - if (!_isTimerPaused)
    445  - return;
     447 + _autoRefreshTimer.Start();
    446 448   
    447  - _autoRefreshTimer.Start();
     449 + _isTimerPaused = false;
     450 + }
    448 451   
    449  - _isTimerPaused = false;
    450  - }
     452 + public void OnViewHide()
     453 + {
     454 + PauseAutoRefreshTimer();
     455 + }
    451 456   
    452  - public void OnViewHide()
    453  - {
    454  - PauseAutoRefreshTimer();
    455  - }
     457 + public void OnViewVisible()
     458 + {
     459 + ResumeAutoRefreshTimer();
     460 + }
     461 + #endregion
    456 462   
    457  - public void OnViewVisible()
    458  - {
    459  - ResumeAutoRefreshTimer();
    460  - }
    461  - #endregion
    462  - 
    463  - #region Events
    464  - private void ArpTable_UserHasCanceled(object sender, EventArgs e)
    465  - {
    466  - StatusMessage = Localization.Resources.Strings.CanceledByUserMessage;
    467  - IsStatusMessageDisplayed = true;
    468  - }
     463 + #region Events
     464 + private void ArpTable_UserHasCanceled(object sender, EventArgs e)
     465 + {
     466 + StatusMessage = Localization.Resources.Strings.CanceledByUserMessage;
     467 + IsStatusMessageDisplayed = true;
     468 + }
    469 469   
    470  - private async void AutoRefreshTimer_Tick(object sender, EventArgs e)
    471  - {
    472  - // Stop timer...
    473  - _autoRefreshTimer.Stop();
     470 + private async void AutoRefreshTimer_Tick(object sender, EventArgs e)
     471 + {
     472 + // Stop timer...
     473 + _autoRefreshTimer.Stop();
    474 474   
    475  - // Refresh
    476  - await Refresh();
     475 + // Refresh
     476 + await Refresh();
    477 477   
    478  - // Restart timer...
    479  - _autoRefreshTimer.Start();
    480  - }
    481  - #endregion
     478 + // Restart timer...
     479 + _autoRefreshTimer.Start();
    482 480   }
     481 + #endregion
    483 482  }
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/AWSProfileViewModel.cs
    skipped 2 lines
    3 3  using System.Windows.Input;
    4 4  using NETworkManager.Models.AWS;
    5 5   
    6  -namespace NETworkManager.ViewModels
     6 +namespace NETworkManager.ViewModels;
     7 + 
     8 +public class AWSProfileViewModel : ViewModelBase
    7 9  {
    8  - public class AWSProfileViewModel : ViewModelBase
    9  - {
    10  - private readonly bool _isLoading;
     10 + private readonly bool _isLoading;
    11 11   
    12  - public ICommand SaveCommand { get; }
     12 + public ICommand SaveCommand { get; }
    13 13   
    14  - public ICommand CancelCommand { get; }
     14 + public ICommand CancelCommand { get; }
    15 15   
    16  - private bool _isEnabled;
    17  - public bool IsEnabled
     16 + private bool _isEnabled;
     17 + public bool IsEnabled
     18 + {
     19 + get => _isEnabled;
     20 + set
    18 21   {
    19  - get => _isEnabled;
    20  - set
    21  - {
    22  - if (_isEnabled == value)
    23  - return;
     22 + if (_isEnabled == value)
     23 + return;
    24 24   
    25  - _isEnabled = value;
     25 + _isEnabled = value;
    26 26   
    27  - if (!_isLoading)
    28  - Validate();
     27 + if (!_isLoading)
     28 + Validate();
    29 29   
    30  - OnPropertyChanged();
    31  - }
     30 + OnPropertyChanged();
    32 31   }
     32 + }
    33 33   
    34  - private string _profile;
    35  - public string Profile
     34 + private string _profile;
     35 + public string Profile
     36 + {
     37 + get => _profile;
     38 + set
    36 39   {
    37  - get => _profile;
    38  - set
    39  - {
    40  - if (_profile == value)
    41  - return;
     40 + if (_profile == value)
     41 + return;
    42 42   
    43  - _profile = value;
     43 + _profile = value;
    44 44   
    45  - if (!_isLoading)
    46  - Validate();
     45 + if (!_isLoading)
     46 + Validate();
    47 47   
    48  - OnPropertyChanged();
    49  - }
     48 + OnPropertyChanged();
    50 49   }
     50 + }
    51 51   
    52  - private string _region;
    53  - public string Region
     52 + private string _region;
     53 + public string Region
     54 + {
     55 + get => _region;
     56 + set
    54 57   {
    55  - get => _region;
    56  - set
    57  - {
    58  - if (_region == value)
    59  - return;
     58 + if (_region == value)
     59 + return;
    60 60   
    61  - _region = value;
     61 + _region = value;
    62 62   
    63  - if (!_isLoading)
    64  - Validate();
     63 + if (!_isLoading)
     64 + Validate();
    65 65   
    66  - OnPropertyChanged();
    67  - }
     66 + OnPropertyChanged();
    68 67   }
     68 + }
    69 69   
    70  - private readonly AWSProfileInfo _info;
     70 + private readonly AWSProfileInfo _info;
    71 71   
    72  - private bool _infoChanged;
    73  - public bool InfoChanged
     72 + private bool _infoChanged;
     73 + public bool InfoChanged
     74 + {
     75 + get => _infoChanged;
     76 + set
    74 77   {
    75  - get => _infoChanged;
    76  - set
    77  - {
    78  - if (value == _infoChanged)
    79  - return;
     78 + if (value == _infoChanged)
     79 + return;
    80 80   
    81  - _infoChanged = value;
    82  - OnPropertyChanged();
    83  - }
     81 + _infoChanged = value;
     82 + OnPropertyChanged();
    84 83   }
     84 + }
    85 85   
    86  - private bool _isEdited;
    87  - public bool IsEdited
     86 + private bool _isEdited;
     87 + public bool IsEdited
     88 + {
     89 + get => _isEdited;
     90 + set
    88 91   {
    89  - get => _isEdited;
    90  - set
    91  - {
    92  - if (value == _isEdited)
    93  - return;
     92 + if (value == _isEdited)
     93 + return;
    94 94   
    95  - _isEdited = value;
    96  - OnPropertyChanged();
    97  - }
     95 + _isEdited = value;
     96 + OnPropertyChanged();
    98 97   }
     98 + }
    99 99   
    100  - public AWSProfileViewModel(Action<AWSProfileViewModel> saveCommand, Action<AWSProfileViewModel> cancelHandler, bool isEdited = false, AWSProfileInfo info = null)
    101  - {
    102  - _isLoading = true;
     100 + public AWSProfileViewModel(Action<AWSProfileViewModel> saveCommand, Action<AWSProfileViewModel> cancelHandler, bool isEdited = false, AWSProfileInfo info = null)
     101 + {
     102 + _isLoading = true;
    103 103   
    104  - SaveCommand = new RelayCommand(p => saveCommand(this));
    105  - CancelCommand = new RelayCommand(p => cancelHandler(this));
     104 + SaveCommand = new RelayCommand(p => saveCommand(this));
     105 + CancelCommand = new RelayCommand(p => cancelHandler(this));
    106 106   
    107  - IsEdited = isEdited;
     107 + IsEdited = isEdited;
    108 108   
    109  - _info = info ?? new AWSProfileInfo();
     109 + _info = info ?? new AWSProfileInfo();
    110 110  
    111  - IsEnabled = _info.IsEnabled;
    112  - Profile = _info.Profile;
    113  - Region = _info.Region;
     111 + IsEnabled = _info.IsEnabled;
     112 + Profile = _info.Profile;
     113 + Region = _info.Region;
    114 114   
    115  - _isLoading = false;
    116  - }
     115 + _isLoading = false;
     116 + }
    117 117   
    118  - public void Validate()
    119  - {
    120  - InfoChanged = _info.IsEnabled != IsEnabled || _info.Profile != Profile || _info.Region != Region;
    121  - }
     118 + public void Validate()
     119 + {
     120 + InfoChanged = _info.IsEnabled != IsEnabled || _info.Profile != Profile || _info.Region != Region;
    122 121   }
    123 122  }
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/AWSSessionManagerConnectViewModel.cs
    skipped 4 lines
    5 5  using System.Windows.Data;
    6 6  using System.Windows.Input;
    7 7   
    8  -namespace NETworkManager.ViewModels
     8 +namespace NETworkManager.ViewModels;
     9 + 
     10 +public class AWSSessionManagerConnectViewModel : ViewModelBase
    9 11  {
    10  - public class AWSSessionManagerConnectViewModel : ViewModelBase
    11  - {
    12  - public ICommand ConnectCommand { get; }
    13  - public ICommand CancelCommand { get; }
     12 + public ICommand ConnectCommand { get; }
     13 + public ICommand CancelCommand { get; }
    14 14   
    15  - private string _instanceID;
    16  - public string InstanceID
     15 + private string _instanceID;
     16 + public string InstanceID
     17 + {
     18 + get => _instanceID;
     19 + set
    17 20   {
    18  - get => _instanceID;
    19  - set
    20  - {
    21  - if (value == _instanceID)
    22  - return;
     21 + if (value == _instanceID)
     22 + return;
    23 23   
    24  - _instanceID = value;
    25  - OnPropertyChanged();
    26  - }
     24 + _instanceID = value;
     25 + OnPropertyChanged();
    27 26   }
     27 + }
    28 28   
    29  - public ICollectionView InstanceIDHistoryView { get; }
     29 + public ICollectionView InstanceIDHistoryView { get; }
    30 30   
    31  - private string _profile;
    32  - public string Profile
     31 + private string _profile;
     32 + public string Profile
     33 + {
     34 + get => _profile;
     35 + set
    33 36   {
    34  - get => _profile;
    35  - set
    36  - {
    37  - if (value == _profile)
    38  - return;
     37 + if (value == _profile)
     38 + return;
    39 39   
    40  - _profile = value;
    41  - OnPropertyChanged();
    42  - }
     40 + _profile = value;
     41 + OnPropertyChanged();
    43 42   }
     43 + }
    44 44   
    45  - public ICollectionView ProfileHistoryView { get; }
     45 + public ICollectionView ProfileHistoryView { get; }
    46 46   
    47  - private string _region;
    48  - public string Region
     47 + private string _region;
     48 + public string Region
     49 + {
     50 + get => _region;
     51 + set
    49 52   {
    50  - get => _region;
    51  - set
    52  - {
    53  - if (value == _region)
    54  - return;
     53 + if (value == _region)
     54 + return;
    55 55   
    56  - _region = value;
    57  - OnPropertyChanged();
    58  - }
     56 + _region = value;
     57 + OnPropertyChanged();
    59 58   }
     59 + }
    60 60   
    61  - public ICollectionView RegionHistoryView { get; }
     61 + public ICollectionView RegionHistoryView { get; }
    62 62   
    63  - public AWSSessionManagerConnectViewModel(Action<AWSSessionManagerConnectViewModel> connectCommand, Action<AWSSessionManagerConnectViewModel> cancelHandler)
    64  - {
    65  - ConnectCommand = new RelayCommand(p => connectCommand(this));
    66  - CancelCommand = new RelayCommand(p => cancelHandler(this));
     63 + public AWSSessionManagerConnectViewModel(Action<AWSSessionManagerConnectViewModel> connectCommand, Action<AWSSessionManagerConnectViewModel> cancelHandler)
     64 + {
     65 + ConnectCommand = new RelayCommand(p => connectCommand(this));
     66 + CancelCommand = new RelayCommand(p => cancelHandler(this));
    67 67   
    68  - InstanceIDHistoryView = CollectionViewSource.GetDefaultView(SettingsManager.Current.AWSSessionManager_InstanceIDHistory);
    69  - ProfileHistoryView = CollectionViewSource.GetDefaultView(SettingsManager.Current.AWSSessionManager_ProfileHistory);
    70  - RegionHistoryView = CollectionViewSource.GetDefaultView(SettingsManager.Current.AWSSessionManager_RegionHistory);
     68 + InstanceIDHistoryView = CollectionViewSource.GetDefaultView(SettingsManager.Current.AWSSessionManager_InstanceIDHistory);
     69 + ProfileHistoryView = CollectionViewSource.GetDefaultView(SettingsManager.Current.AWSSessionManager_ProfileHistory);
     70 + RegionHistoryView = CollectionViewSource.GetDefaultView(SettingsManager.Current.AWSSessionManager_RegionHistory);
    71 71   
    72  - LoadSettings();
    73  - }
     72 + LoadSettings();
     73 + }
    74 74   
    75  - private void LoadSettings()
    76  - {
    77  - Profile = SettingsManager.Current.AWSSessionManager_DefaultProfile;
    78  - Region = SettingsManager.Current.AWSSessionManager_DefaultRegion;
    79  - }
     75 + private void LoadSettings()
     76 + {
     77 + Profile = SettingsManager.Current.AWSSessionManager_DefaultProfile;
     78 + Region = SettingsManager.Current.AWSSessionManager_DefaultRegion;
    80 79   }
    81 80  }
    82 81   
Please wait...
Page is in error, reload to recover