/ src / modules / EnvironmentVariables / EnvironmentVariablesUILib / EnvironmentVariablesMainPage.xaml.cs
EnvironmentVariablesMainPage.xaml.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Linq; 7 using System.Threading.Tasks; 8 using System.Windows.Input; 9 10 using CommunityToolkit.Mvvm.Input; 11 using EnvironmentVariablesUILib.Models; 12 using EnvironmentVariablesUILib.ViewModels; 13 using Microsoft.UI.Xaml.Controls; 14 15 namespace EnvironmentVariablesUILib 16 { 17 public sealed partial class EnvironmentVariablesMainPage : Page 18 { 19 private sealed class RelayCommandParameter 20 { 21 public RelayCommandParameter(Variable variable, VariablesSet set) 22 { 23 Variable = variable; 24 this.Set = set; 25 } 26 27 public Variable Variable { get; set; } 28 29 public VariablesSet Set { get; set; } 30 } 31 32 public MainViewModel ViewModel { get; private set; } 33 34 public ICommand EditCommand => new RelayCommand<RelayCommandParameter>(EditVariable); 35 36 public ICommand NewProfileCommand => new AsyncRelayCommand(AddProfileAsync); 37 38 public ICommand AddProfileCommand => new RelayCommand(AddProfile); 39 40 public ICommand UpdateProfileCommand => new RelayCommand(UpdateProfile); 41 42 public ICommand AddVariableCommand => new RelayCommand(AddVariable); 43 44 public ICommand CancelAddVariableCommand => new RelayCommand(CancelAddVariable); 45 46 public ICommand AddDefaultVariableCommand => new RelayCommand<DefaultVariablesSet>(AddDefaultVariable); 47 48 public EnvironmentVariablesMainPage(MainViewModel viewModel) 49 { 50 this.InitializeComponent(); 51 ViewModel = viewModel; 52 DataContext = ViewModel; 53 54 ViewModel.LoadEnvironmentVariables(); 55 } 56 57 private async Task ShowEditDialogAsync(Variable variable, VariablesSet parentSet) 58 { 59 var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; 60 61 EditVariableDialog.Title = resourceLoader.GetString("EditVariableDialog_Title"); 62 EditVariableDialog.PrimaryButtonText = resourceLoader.GetString("SaveBtn"); 63 EditVariableDialog.SecondaryButtonText = resourceLoader.GetString("CancelBtn"); 64 EditVariableDialog.PrimaryButtonCommand = EditCommand; 65 EditVariableDialog.PrimaryButtonCommandParameter = new RelayCommandParameter(variable, parentSet); 66 67 var clone = variable.Clone(); 68 EditVariableDialog.DataContext = clone; 69 70 await EditVariableDialog.ShowAsync(); 71 } 72 73 private async void EditVariable_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 74 { 75 var btn = sender as MenuFlyoutItem; 76 var variablesSet = btn.DataContext as VariablesSet; 77 var variable = btn.CommandParameter as Variable; 78 79 if (variable != null) 80 { 81 await ShowEditDialogAsync(variable, variablesSet); 82 } 83 } 84 85 private void EditVariable(RelayCommandParameter param) 86 { 87 var variableSet = param.Set as ProfileVariablesSet; 88 var original = param.Variable; 89 var edited = EditVariableDialog.DataContext as Variable; 90 ViewModel.EditVariable(original, edited, variableSet); 91 } 92 93 private async Task AddProfileAsync() 94 { 95 SwitchViewsSegmentedView.SelectedIndex = 0; 96 97 var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; 98 AddProfileDialog.Title = resourceLoader.GetString("AddNewProfileDialog_Title"); 99 AddProfileDialog.PrimaryButtonText = resourceLoader.GetString("AddBtn"); 100 AddProfileDialog.SecondaryButtonText = resourceLoader.GetString("CancelBtn"); 101 AddProfileDialog.PrimaryButtonCommand = AddProfileCommand; 102 AddProfileDialog.DataContext = new ProfileVariablesSet(Guid.NewGuid(), string.Empty); 103 104 await AddProfileDialog.ShowAsync(); 105 } 106 107 private void AddProfile() 108 { 109 var profile = AddProfileDialog.DataContext as ProfileVariablesSet; 110 ViewModel.AddProfile(profile); 111 } 112 113 private void UpdateProfile() 114 { 115 var updatedProfile = AddProfileDialog.DataContext as ProfileVariablesSet; 116 ViewModel.UpdateProfile(updatedProfile); 117 } 118 119 private async void RemoveProfileBtn_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 120 { 121 var button = sender as MenuFlyoutItem; 122 var profile = button.CommandParameter as ProfileVariablesSet; 123 124 if (profile != null) 125 { 126 var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; 127 ContentDialog dialog = new ContentDialog(); 128 dialog.XamlRoot = RootPage.XamlRoot; 129 dialog.Title = profile.Name; 130 dialog.PrimaryButtonText = resourceLoader.GetString("Yes"); 131 dialog.CloseButtonText = resourceLoader.GetString("No"); 132 dialog.DefaultButton = ContentDialogButton.Primary; 133 dialog.Content = new TextBlock() { Text = resourceLoader.GetString("Delete_Dialog_Description"), TextWrapping = Microsoft.UI.Xaml.TextWrapping.WrapWholeWords }; 134 dialog.PrimaryButtonClick += (s, args) => 135 { 136 ViewModel.RemoveProfile(profile); 137 }; 138 139 var result = await dialog.ShowAsync(); 140 } 141 } 142 143 private void AddVariable() 144 { 145 var profile = AddProfileDialog.DataContext as ProfileVariablesSet; 146 if (profile != null) 147 { 148 if (AddVariableSwitchPresenter.Value as string == "NewVariable") 149 { 150 profile.Variables.Add(new Variable(AddNewVariableName.Text, AddNewVariableValue.Text, VariablesSetType.Profile)); 151 } 152 else 153 { 154 foreach (Variable variable in ExistingVariablesListView.SelectedItems) 155 { 156 if (!profile.Variables.Where(x => x.Name == variable.Name).Any()) 157 { 158 var clone = variable.Clone(true); 159 profile.Variables.Add(clone); 160 } 161 } 162 } 163 } 164 165 AddNewVariableName.Text = string.Empty; 166 AddNewVariableValue.Text = string.Empty; 167 ExistingVariablesListView.SelectionChanged -= ExistingVariablesListView_SelectionChanged; 168 ExistingVariablesListView.SelectedItems.Clear(); 169 ExistingVariablesListView.SelectionChanged += ExistingVariablesListView_SelectionChanged; 170 AddVariableFlyout.Hide(); 171 } 172 173 private void CancelAddVariable() 174 { 175 AddNewVariableName.Text = string.Empty; 176 AddNewVariableValue.Text = string.Empty; 177 178 ExistingVariablesListView.SelectionChanged -= ExistingVariablesListView_SelectionChanged; 179 ExistingVariablesListView.SelectedItems.Clear(); 180 ExistingVariablesListView.SelectionChanged += ExistingVariablesListView_SelectionChanged; 181 182 AddVariableFlyout.Hide(); 183 } 184 185 private void AddDefaultVariable(DefaultVariablesSet set) 186 { 187 var variable = AddDefaultVariableDialog.DataContext as Variable; 188 var type = set.Type; 189 190 ViewModel.AddDefaultVariable(variable, type); 191 } 192 193 private async void Delete_Variable_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 194 { 195 MenuFlyoutItem selectedItem = sender as MenuFlyoutItem; 196 var variableSet = selectedItem.DataContext as ProfileVariablesSet; 197 var variable = selectedItem.CommandParameter as Variable; 198 199 if (variable != null) 200 { 201 var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; 202 ContentDialog dialog = new ContentDialog(); 203 dialog.XamlRoot = RootPage.XamlRoot; 204 dialog.Title = variable.Name; 205 dialog.PrimaryButtonText = resourceLoader.GetString("Yes"); 206 dialog.CloseButtonText = resourceLoader.GetString("No"); 207 dialog.DefaultButton = ContentDialogButton.Primary; 208 dialog.Content = new TextBlock() { Text = resourceLoader.GetString("Delete_Variable_Description"), TextWrapping = Microsoft.UI.Xaml.TextWrapping.WrapWholeWords }; 209 dialog.PrimaryButtonClick += (s, args) => 210 { 211 ViewModel.DeleteVariable(variable, variableSet); 212 }; 213 var result = await dialog.ShowAsync(); 214 } 215 } 216 217 private void AddNewVariableName_TextChanged(object sender, TextChangedEventArgs e) 218 { 219 TextBox nameTxtBox = sender as TextBox; 220 var profile = AddProfileDialog.DataContext as ProfileVariablesSet; 221 222 if (nameTxtBox != null) 223 { 224 if (nameTxtBox.Text.Length == 0 || nameTxtBox.Text.Length >= 255 || profile.Variables.Where(x => x.Name.Equals(nameTxtBox.Text, StringComparison.OrdinalIgnoreCase)).Any()) 225 { 226 ConfirmAddVariableBtn.IsEnabled = false; 227 } 228 else 229 { 230 ConfirmAddVariableBtn.IsEnabled = true; 231 } 232 } 233 } 234 235 private void ReloadButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 236 { 237 ViewModel.LoadEnvironmentVariables(); 238 ViewModel.EnvironmentState = EnvironmentState.Unchanged; 239 } 240 241 private void ExistingVariablesListView_SelectionChanged(object sender, SelectionChangedEventArgs e) 242 { 243 var profile = AddProfileDialog.DataContext as ProfileVariablesSet; 244 245 int toRemove = -1; 246 247 if (e.AddedItems.Count > 0) 248 { 249 var list = sender as ListView; 250 var duplicates = list.SelectedItems.GroupBy(x => ((Variable)x).Name.ToLowerInvariant()).Where(g => g.Count() > 1).ToList(); 251 252 foreach (var dup in duplicates) 253 { 254 ExistingVariablesListView.SelectionChanged -= ExistingVariablesListView_SelectionChanged; 255 list.SelectedItems.Remove(dup.ElementAt(1)); 256 ExistingVariablesListView.SelectionChanged += ExistingVariablesListView_SelectionChanged; 257 } 258 } 259 260 if (e.RemovedItems.Count > 0) 261 { 262 Variable removedVariable = e.RemovedItems[0] as Variable; 263 for (int i = 0; i < profile.Variables.Count; i++) 264 { 265 if (profile.Variables[i].Name == removedVariable.Name && profile.Variables[i].Values == removedVariable.Values) 266 { 267 toRemove = i; 268 break; 269 } 270 } 271 272 if (toRemove != -1) 273 { 274 profile.Variables.RemoveAt(toRemove); 275 } 276 } 277 278 ConfirmAddVariableBtn.IsEnabled = false; 279 foreach (Variable variable in ExistingVariablesListView.SelectedItems) 280 { 281 if (variable != null) 282 { 283 if (!profile.Variables.Where(x => x.Name.Equals(variable.Name, StringComparison.Ordinal) && x.Values.Equals(variable.Values, StringComparison.Ordinal)).Any()) 284 { 285 ConfirmAddVariableBtn.IsEnabled = true; 286 break; 287 } 288 } 289 } 290 } 291 292 private async void EditProfileBtn_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 293 { 294 SwitchViewsSegmentedView.SelectedIndex = 0; 295 296 var button = sender as MenuFlyoutItem; 297 var profile = button.CommandParameter as ProfileVariablesSet; 298 299 if (profile != null) 300 { 301 var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; 302 AddProfileDialog.Title = resourceLoader.GetString("EditProfileDialog_Title"); 303 AddProfileDialog.PrimaryButtonText = resourceLoader.GetString("SaveBtn"); 304 AddProfileDialog.SecondaryButtonText = resourceLoader.GetString("CancelBtn"); 305 AddProfileDialog.PrimaryButtonCommand = UpdateProfileCommand; 306 AddProfileDialog.DataContext = profile.Clone(); 307 await AddProfileDialog.ShowAsync(); 308 } 309 } 310 311 private void ExistingVariablesListView_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 312 { 313 var profile = AddProfileDialog.DataContext as ProfileVariablesSet; 314 315 foreach (Variable item in ExistingVariablesListView.Items) 316 { 317 if (item != null) 318 { 319 foreach (var profileItem in profile.Variables) 320 { 321 if (profileItem.Name == item.Name && profileItem.Values == item.Values) 322 { 323 if (ExistingVariablesListView.SelectedItems.Where(x => ((Variable)x).Name.Equals(profileItem.Name, StringComparison.OrdinalIgnoreCase)).Any()) 324 { 325 continue; 326 } 327 328 ExistingVariablesListView.SelectionChanged -= ExistingVariablesListView_SelectionChanged; 329 ExistingVariablesListView.SelectedItems.Add(item); 330 ExistingVariablesListView.SelectionChanged += ExistingVariablesListView_SelectionChanged; 331 } 332 } 333 } 334 } 335 } 336 337 private async Task ShowAddDefaultVariableDialogAsync(DefaultVariablesSet set) 338 { 339 var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; 340 341 AddDefaultVariableDialog.Title = resourceLoader.GetString("AddVariable_Title"); 342 AddDefaultVariableDialog.PrimaryButtonText = resourceLoader.GetString("SaveBtn"); 343 AddDefaultVariableDialog.SecondaryButtonText = resourceLoader.GetString("CancelBtn"); 344 AddDefaultVariableDialog.PrimaryButtonCommand = AddDefaultVariableCommand; 345 AddDefaultVariableDialog.PrimaryButtonCommandParameter = set; 346 347 var variableType = set.Id == VariablesSet.SystemGuid ? VariablesSetType.System : VariablesSetType.User; 348 AddDefaultVariableDialog.DataContext = new Variable(string.Empty, string.Empty, variableType); 349 350 await AddDefaultVariableDialog.ShowAsync(); 351 } 352 353 private async void AddDefaultVariableBtn_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 354 { 355 var button = sender as Button; 356 var defaultVariableSet = button.CommandParameter as DefaultVariablesSet; 357 358 if (defaultVariableSet != null) 359 { 360 await ShowAddDefaultVariableDialogAsync(defaultVariableSet); 361 } 362 } 363 364 private void EditVariableDialogNameTxtBox_TextChanged(object sender, TextChangedEventArgs e) 365 { 366 var variable = EditVariableDialog.DataContext as Variable; 367 var param = EditVariableDialog.PrimaryButtonCommandParameter as RelayCommandParameter; 368 var variableSet = param.Set; 369 370 if (variableSet == null) 371 { 372 // default set 373 variableSet = variable.ParentType == VariablesSetType.User ? ViewModel.UserDefaultSet : ViewModel.SystemDefaultSet; 374 } 375 376 if (variableSet != null) 377 { 378 if (variableSet.Variables.Where(x => x.Name.Equals(EditVariableDialogNameTxtBox.Text, StringComparison.OrdinalIgnoreCase)).Any() || !variable.Valid) 379 { 380 EditVariableDialog.IsPrimaryButtonEnabled = false; 381 } 382 else 383 { 384 EditVariableDialog.IsPrimaryButtonEnabled = true; 385 } 386 } 387 388 if (!variable.Validate()) 389 { 390 EditVariableDialog.IsPrimaryButtonEnabled = false; 391 } 392 } 393 394 private void AddDefaultVariableNameTxtBox_TextChanged(object sender, TextChangedEventArgs e) 395 { 396 TextBox nameTxtBox = sender as TextBox; 397 var variable = AddDefaultVariableDialog.DataContext as Variable; 398 var defaultSet = variable.ParentType == VariablesSetType.User ? ViewModel.UserDefaultSet : ViewModel.SystemDefaultSet; 399 400 if (nameTxtBox != null) 401 { 402 if (nameTxtBox.Text.Length == 0 || defaultSet.Variables.Where(x => x.Name.Equals(nameTxtBox.Text, StringComparison.OrdinalIgnoreCase)).Any()) 403 { 404 AddDefaultVariableDialog.IsPrimaryButtonEnabled = false; 405 } 406 else 407 { 408 AddDefaultVariableDialog.IsPrimaryButtonEnabled = true; 409 } 410 } 411 412 if (!variable.Validate()) 413 { 414 AddDefaultVariableDialog.IsPrimaryButtonEnabled = false; 415 } 416 } 417 418 private void EditVariableDialogValueTxtBox_TextChanged(object sender, TextChangedEventArgs e) 419 { 420 var txtBox = sender as TextBox; 421 var variable = EditVariableDialog.DataContext as Variable; 422 EditVariableDialog.IsPrimaryButtonEnabled = true; 423 424 variable.ValuesList = Variable.ValuesStringToValuesListItemCollection(txtBox.Text); 425 } 426 427 private void ReorderButtonUp_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 428 { 429 var listItem = ((MenuFlyoutItem)sender).DataContext as Variable.ValuesListItem; 430 if (listItem == null) 431 { 432 return; 433 } 434 435 var variable = EditVariableDialog.DataContext as Variable; 436 437 var index = variable.ValuesList.IndexOf(listItem); 438 if (index > 0) 439 { 440 variable.ValuesList.Move(index, index - 1); 441 } 442 443 var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); 444 EditVariableDialogValueTxtBox.Text = newValues; 445 } 446 447 private void ReorderButtonDown_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 448 { 449 var listItem = ((MenuFlyoutItem)sender).DataContext as Variable.ValuesListItem; 450 if (listItem == null) 451 { 452 return; 453 } 454 455 var variable = EditVariableDialog.DataContext as Variable; 456 var btn = EditVariableDialog.PrimaryButtonCommandParameter as Button; 457 458 var index = variable.ValuesList.IndexOf(listItem); 459 if (index < variable.ValuesList.Count - 1) 460 { 461 variable.ValuesList.Move(index, index + 1); 462 } 463 464 var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); 465 EditVariableDialogValueTxtBox.Text = newValues; 466 } 467 468 private void RemoveListVariableButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 469 { 470 var listItem = ((MenuFlyoutItem)sender).DataContext as Variable.ValuesListItem; 471 if (listItem == null) 472 { 473 return; 474 } 475 476 var variable = EditVariableDialog.DataContext as Variable; 477 variable.ValuesList.Remove(listItem); 478 479 var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); 480 EditVariableDialogValueTxtBox.Text = newValues; 481 } 482 483 private void InsertListEntryBeforeButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 484 { 485 var listItem = (sender as MenuFlyoutItem)?.DataContext as Variable.ValuesListItem; 486 if (listItem == null) 487 { 488 return; 489 } 490 491 var variable = EditVariableDialog.DataContext as Variable; 492 var index = variable.ValuesList.IndexOf(listItem); 493 variable.ValuesList.Insert(index, new Variable.ValuesListItem { Text = string.Empty }); 494 495 var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); 496 EditVariableDialogValueTxtBox.TextChanged -= EditVariableDialogValueTxtBox_TextChanged; 497 EditVariableDialogValueTxtBox.Text = newValues; 498 EditVariableDialogValueTxtBox.TextChanged += EditVariableDialogValueTxtBox_TextChanged; 499 } 500 501 private void InsertListEntryAfterButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 502 { 503 var listItem = (sender as MenuFlyoutItem)?.DataContext as Variable.ValuesListItem; 504 if (listItem == null) 505 { 506 return; 507 } 508 509 var variable = EditVariableDialog.DataContext as Variable; 510 var index = variable.ValuesList.IndexOf(listItem); 511 variable.ValuesList.Insert(index + 1, new Variable.ValuesListItem { Text = string.Empty }); 512 513 var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); 514 EditVariableDialogValueTxtBox.TextChanged -= EditVariableDialogValueTxtBox_TextChanged; 515 EditVariableDialogValueTxtBox.Text = newValues; 516 EditVariableDialogValueTxtBox.TextChanged += EditVariableDialogValueTxtBox_TextChanged; 517 } 518 519 private void EditVariableValuesListTextBox_LostFocus(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 520 { 521 var listItem = (sender as TextBox)?.DataContext as Variable.ValuesListItem; 522 if (listItem == null) 523 { 524 return; 525 } 526 527 if (listItem.Text == (sender as TextBox)?.Text) 528 { 529 return; 530 } 531 532 listItem.Text = (sender as TextBox)?.Text; 533 var variable = EditVariableDialog.DataContext as Variable; 534 535 var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); 536 EditVariableDialogValueTxtBox.TextChanged -= EditVariableDialogValueTxtBox_TextChanged; 537 EditVariableDialogValueTxtBox.Text = newValues; 538 EditVariableDialogValueTxtBox.TextChanged += EditVariableDialogValueTxtBox_TextChanged; 539 } 540 541 private void InvalidStateInfoBar_CloseButtonClick(InfoBar sender, object args) 542 { 543 ViewModel.EnvironmentState = EnvironmentState.Unchanged; 544 } 545 546 private void AddVariableFlyout_Closed(object sender, object e) 547 { 548 CancelAddVariable(); 549 ConfirmAddVariableBtn.IsEnabled = false; 550 } 551 } 552 }