/
githubmirror
/
PowerToys
Обзор
Документация
Войти
/
githubmirror
/
PowerToys
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesMainPage.xaml.cs
603 строки
24 KB
Dave Rayment
[EnvironmentVariables] Validation fixes, centralised validation, error message improvements (#46837)
05 авг 2026, 11:42
Не верифицирован
05 авг 2026, 11:42
3079a3c
Код
Авторство
О чём код?
// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Linq; using System.Threading.Tasks; using System.Windows.Input; using CommunityToolkit.Mvvm.Input; using EnvironmentVariablesUILib.Helpers; using EnvironmentVariablesUILib.Models; using EnvironmentVariablesUILib.ViewModels; using Microsoft.UI.Xaml.Controls; namespace EnvironmentVariablesUILib { public sealed partial class EnvironmentVariablesMainPage : Page { private sealed class RelayCommandParameter { public RelayCommandParameter(Variable variable, VariablesSet set) { Variable = variable; this.Set = set; } public Variable Variable { get; set; } public VariablesSet Set { get; set; } } public MainViewModel ViewModel { get; private set; } public ICommand EditCommand => new RelayCommand<RelayCommandParameter>(EditVariable); public ICommand NewProfileCommand => new AsyncRelayCommand(AddProfileAsync); public ICommand AddProfileCommand => new RelayCommand(AddProfile); public ICommand UpdateProfileCommand => new RelayCommand(UpdateProfile); public ICommand AddVariableCommand => new RelayCommand(AddVariable); public ICommand CancelAddVariableCommand => new RelayCommand(CancelAddVariable); public ICommand AddDefaultVariableCommand => new RelayCommand<DefaultVariablesSet>(AddDefaultVariable); public EnvironmentVariablesMainPage(MainViewModel viewModel) { this.InitializeComponent(); ViewModel = viewModel; DataContext = ViewModel; ViewModel.LoadEnvironmentVariables(); } private async Task ShowEditDialogAsync(Variable variable, VariablesSet parentSet) { var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; EditVariableDialog.Title = resourceLoader.GetString("EditVariableDialog_Title"); EditVariableDialog.PrimaryButtonText = resourceLoader.GetString("SaveBtn"); EditVariableDialog.SecondaryButtonText = resourceLoader.GetString("CancelBtn"); EditVariableDialog.PrimaryButtonCommand = EditCommand; EditVariableDialog.PrimaryButtonCommandParameter = new RelayCommandParameter(variable, parentSet); var clone = variable.Clone(); EditVariableDialog.DataContext = clone; UpdateEditVariableDialogPrimaryButtonState(); await EditVariableDialog.ShowAsync(); } private async void EditVariable_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { var btn = sender as MenuFlyoutItem; var variablesSet = btn.DataContext as VariablesSet; var variable = btn.CommandParameter as Variable; if (variable != null) { await ShowEditDialogAsync(variable, variablesSet); } } private void EditVariable(RelayCommandParameter param) { var variableSet = param.Set as ProfileVariablesSet; var original = param.Variable; var edited = EditVariableDialog.DataContext as Variable; ViewModel.EditVariable(original, edited, variableSet); } private async Task AddProfileAsync() { SwitchViewsSegmentedView.SelectedIndex = 0; var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; AddProfileDialog.Title = resourceLoader.GetString("AddNewProfileDialog_Title"); AddProfileDialog.PrimaryButtonText = resourceLoader.GetString("AddBtn"); AddProfileDialog.SecondaryButtonText = resourceLoader.GetString("CancelBtn"); AddProfileDialog.PrimaryButtonCommand = AddProfileCommand; AddProfileDialog.DataContext = new ProfileVariablesSet(Guid.NewGuid(), string.Empty); await AddProfileDialog.ShowAsync(); } private void AddProfile() { var profile = AddProfileDialog.DataContext as ProfileVariablesSet; ViewModel.AddProfile(profile); } private void UpdateProfile() { var updatedProfile = AddProfileDialog.DataContext as ProfileVariablesSet; ViewModel.UpdateProfile(updatedProfile); } private async void RemoveProfileBtn_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { var button = sender as MenuFlyoutItem; var profile = button.CommandParameter as ProfileVariablesSet; if (profile != null) { var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; ContentDialog dialog = new ContentDialog(); dialog.XamlRoot = RootPage.XamlRoot; dialog.Title = profile.Name; dialog.PrimaryButtonText = resourceLoader.GetString("Yes"); dialog.CloseButtonText = resourceLoader.GetString("No"); dialog.DefaultButton = ContentDialogButton.Primary; dialog.Content = new TextBlock() { Text = resourceLoader.GetString("Delete_Dialog_Description"), TextWrapping = Microsoft.UI.Xaml.TextWrapping.WrapWholeWords }; dialog.PrimaryButtonClick += (s, args) => { ViewModel.RemoveProfile(profile); }; var result = await dialog.ShowAsync(); } } private void AddVariable() { var profile = AddProfileDialog.DataContext as ProfileVariablesSet; if (profile != null) { if (AddVariableSwitchPresenter.Value as string == "NewVariable") { var variable = new Variable(AddNewVariableName.Text, AddNewVariableValue.Text, VariablesSetType.Profile); if (variable.Validate() && !profile.Variables.Any(x => EnvironmentVariableComparisonHelper.NamesEqual(x.Name, variable.Name))) { profile.Variables.Add(variable); } } else { foreach (Variable variable in ExistingVariablesListView.SelectedItems) { if (!profile.Variables.Any(x => EnvironmentVariableComparisonHelper.NamesEqual(x.Name, variable.Name))) { var clone = variable.Clone(true); profile.Variables.Add(clone); } } } } AddNewVariableName.Text = string.Empty; AddNewVariableValue.Text = string.Empty; ExistingVariablesListView.SelectionChanged -= ExistingVariablesListView_SelectionChanged; ExistingVariablesListView.SelectedItems.Clear(); ExistingVariablesListView.SelectionChanged += ExistingVariablesListView_SelectionChanged; AddVariableFlyout.Hide(); } private void CancelAddVariable() { AddNewVariableName.Text = string.Empty; AddNewVariableValue.Text = string.Empty; ExistingVariablesListView.SelectionChanged -= ExistingVariablesListView_SelectionChanged; ExistingVariablesListView.SelectedItems.Clear(); ExistingVariablesListView.SelectionChanged += ExistingVariablesListView_SelectionChanged; AddVariableFlyout.Hide(); } private void AddDefaultVariable(DefaultVariablesSet set) { var variable = AddDefaultVariableDialog.DataContext as Variable; var type = set.Type; ViewModel.AddDefaultVariable(variable, type); } private async void Delete_Variable_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { MenuFlyoutItem selectedItem = sender as MenuFlyoutItem; var variableSet = selectedItem.DataContext as ProfileVariablesSet; var variable = selectedItem.CommandParameter as Variable; if (variable != null) { var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; ContentDialog dialog = new ContentDialog(); dialog.XamlRoot = RootPage.XamlRoot; dialog.Title = variable.Name; dialog.PrimaryButtonText = resourceLoader.GetString("Yes"); dialog.CloseButtonText = resourceLoader.GetString("No"); dialog.DefaultButton = ContentDialogButton.Primary; dialog.Content = new TextBlock() { Text = resourceLoader.GetString("Delete_Variable_Description"), TextWrapping = Microsoft.UI.Xaml.TextWrapping.WrapWholeWords }; dialog.PrimaryButtonClick += (s, args) => { ViewModel.DeleteVariable(variable, variableSet); }; var result = await dialog.ShowAsync(); } } private void AddNewVariableName_TextChanged(object sender, TextChangedEventArgs e) { UpdateConfirmAddVariableButtonState(); } private void AddNewVariableValue_TextChanged(object sender, TextChangedEventArgs e) { UpdateConfirmAddVariableButtonState(); } private void UpdateConfirmAddVariableButtonState() { var profile = AddProfileDialog.DataContext as ProfileVariablesSet; if (profile == null) { ConfirmAddVariableBtn.IsEnabled = false; return; } if (AddVariableSwitchPresenter.Value as string == "NewVariable") { var variable = new Variable(AddNewVariableName.Text, AddNewVariableValue.Text, VariablesSetType.Profile); ConfirmAddVariableBtn.IsEnabled = variable.Validate() && !profile.Variables.Any(x => EnvironmentVariableComparisonHelper.NamesEqual(x.Name, variable.Name)); return; } ConfirmAddVariableBtn.IsEnabled = ExistingVariablesListView.SelectedItems .OfType<Variable>() .Any(variable => !profile.Variables.Any(x => EnvironmentVariableComparisonHelper.NamesEqual(x.Name, variable.Name))); } private void ReloadButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { ViewModel.LoadEnvironmentVariables(); ViewModel.EnvironmentState = EnvironmentState.Unchanged; } private void ExistingVariablesListView_SelectionChanged(object sender, SelectionChangedEventArgs e) { var profile = AddProfileDialog.DataContext as ProfileVariablesSet; int toRemove = -1; if (e.AddedItems.Count > 0) { var list = sender as ListView; var duplicates = EnvironmentVariableComparisonHelper.GetDuplicateNameGroups( list.SelectedItems.Cast<Variable>()).ToList(); foreach (var dup in duplicates) { ExistingVariablesListView.SelectionChanged -= ExistingVariablesListView_SelectionChanged; list.SelectedItems.Remove(dup.ElementAt(1)); ExistingVariablesListView.SelectionChanged += ExistingVariablesListView_SelectionChanged; } } if (e.RemovedItems.Count > 0) { Variable removedVariable = e.RemovedItems[0] as Variable; for (int i = 0; i < profile.Variables.Count; i++) { if (EnvironmentVariableComparisonHelper.EntriesEqual(profile.Variables[i], removedVariable)) { toRemove = i; break; } } if (toRemove != -1) { profile.Variables.RemoveAt(toRemove); } } UpdateConfirmAddVariableButtonState(); } private async void EditProfileBtn_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { SwitchViewsSegmentedView.SelectedIndex = 0; var button = sender as MenuFlyoutItem; var profile = button.CommandParameter as ProfileVariablesSet; if (profile != null) { var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; AddProfileDialog.Title = resourceLoader.GetString("EditProfileDialog_Title"); AddProfileDialog.PrimaryButtonText = resourceLoader.GetString("SaveBtn"); AddProfileDialog.SecondaryButtonText = resourceLoader.GetString("CancelBtn"); AddProfileDialog.PrimaryButtonCommand = UpdateProfileCommand; AddProfileDialog.DataContext = profile.Clone(); await AddProfileDialog.ShowAsync(); } } private void ExistingVariablesListView_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { var profile = AddProfileDialog.DataContext as ProfileVariablesSet; foreach (Variable item in ExistingVariablesListView.Items) { if (item != null) { foreach (var profileItem in profile.Variables) { if (EnvironmentVariableComparisonHelper.EntriesEqual(profileItem, item)) { if (ExistingVariablesListView.SelectedItems.Any(x => EnvironmentVariableComparisonHelper.NamesEqual(((Variable)x).Name, profileItem.Name))) { continue; } ExistingVariablesListView.SelectionChanged -= ExistingVariablesListView_SelectionChanged; ExistingVariablesListView.SelectedItems.Add(item); ExistingVariablesListView.SelectionChanged += ExistingVariablesListView_SelectionChanged; } } } } } private async Task ShowAddDefaultVariableDialogAsync(DefaultVariablesSet set) { var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; AddDefaultVariableDialog.Title = resourceLoader.GetString("AddVariable_Title"); AddDefaultVariableDialog.PrimaryButtonText = resourceLoader.GetString("SaveBtn"); AddDefaultVariableDialog.SecondaryButtonText = resourceLoader.GetString("CancelBtn"); AddDefaultVariableDialog.PrimaryButtonCommand = AddDefaultVariableCommand; AddDefaultVariableDialog.PrimaryButtonCommandParameter = set; var variableType = set.Id == VariablesSet.SystemGuid ? VariablesSetType.System : VariablesSetType.User; AddDefaultVariableDialog.DataContext = new Variable(string.Empty, string.Empty, variableType); UpdateAddDefaultVariableDialogButtonState(); await AddDefaultVariableDialog.ShowAsync(); } private async void AddDefaultVariableBtn_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { var button = sender as Button; var defaultVariableSet = button.CommandParameter as DefaultVariablesSet; if (defaultVariableSet != null) { await ShowAddDefaultVariableDialogAsync(defaultVariableSet); } } private void EditVariableDialogNameTxtBox_TextChanged(object sender, TextChangedEventArgs e) { var txtBox = sender as TextBox; var variable = EditVariableDialog.DataContext as Variable; // Ensure Name is current regardless of binding timing. if (variable != null) { variable.Name = txtBox.Text; } UpdateEditVariableDialogPrimaryButtonState(); } private void AddDefaultVariableNameTxtBox_TextChanged(object sender, TextChangedEventArgs e) { var txtBox = sender as TextBox; var variable = AddDefaultVariableDialog.DataContext as Variable; // Ensure Name is current regardless of binding timing. if (variable != null) { variable.Name = txtBox.Text; } UpdateAddDefaultVariableDialogButtonState(); } private void AddDefaultVariableValueTxtBox_TextChanged(object sender, TextChangedEventArgs e) { var txtBox = sender as TextBox; var variable = AddDefaultVariableDialog.DataContext as Variable; // Ensure Values is current regardless of binding timing. if (variable != null) { variable.Values = txtBox.Text; } UpdateAddDefaultVariableDialogButtonState(); } private void UpdateAddDefaultVariableDialogButtonState() { var variable = AddDefaultVariableDialog.DataContext as Variable; if (variable == null) { AddDefaultVariableDialog.IsPrimaryButtonEnabled = false; return; } var defaultSet = variable.ParentType == VariablesSetType.User ? ViewModel.UserDefaultSet : ViewModel.SystemDefaultSet; bool isDuplicate = defaultSet.Variables.Any(x => EnvironmentVariableComparisonHelper.NamesEqual(x.Name, variable.Name)); AddDefaultVariableDialog.IsPrimaryButtonEnabled = !isDuplicate && variable.Validate(); } private void EditVariableDialogValueTxtBox_TextChanged(object sender, TextChangedEventArgs e) { var txtBox = sender as TextBox; var variable = EditVariableDialog.DataContext as Variable; // Ensure Values is current regardless of binding timing. variable.Values = txtBox.Text; variable.ValuesList = Variable.ValuesStringToValuesListItemCollection(txtBox.Text); UpdateEditVariableDialogPrimaryButtonState(); } private void UpdateEditVariableDialogPrimaryButtonState() { var variable = EditVariableDialog.DataContext as Variable; var param = EditVariableDialog.PrimaryButtonCommandParameter as RelayCommandParameter; if (variable == null || param == null) { EditVariableDialog.IsPrimaryButtonEnabled = false; return; } var variableSet = param.Set; if (variableSet == null) { variableSet = variable.ParentType == VariablesSetType.User ? ViewModel.UserDefaultSet : ViewModel.SystemDefaultSet; } bool hasDuplicate = variableSet != null && variableSet.Variables.Any(x => !ReferenceEquals(x, param.Variable) && EnvironmentVariableComparisonHelper.NamesEqual(x.Name, variable.Name)); EditVariableDialog.IsPrimaryButtonEnabled = !hasDuplicate && variable.Validate(); } private void ReorderButtonUp_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { var listItem = ((MenuFlyoutItem)sender).DataContext as Variable.ValuesListItem; if (listItem == null) { return; } var variable = EditVariableDialog.DataContext as Variable; var index = variable.ValuesList.IndexOf(listItem); if (index > 0) { variable.ValuesList.Move(index, index - 1); } var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); EditVariableDialogValueTxtBox.Text = newValues; } private void ReorderButtonDown_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { var listItem = ((MenuFlyoutItem)sender).DataContext as Variable.ValuesListItem; if (listItem == null) { return; } var variable = EditVariableDialog.DataContext as Variable; var btn = EditVariableDialog.PrimaryButtonCommandParameter as Button; var index = variable.ValuesList.IndexOf(listItem); if (index < variable.ValuesList.Count - 1) { variable.ValuesList.Move(index, index + 1); } var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); EditVariableDialogValueTxtBox.Text = newValues; } private void RemoveListVariableButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { var listItem = ((MenuFlyoutItem)sender).DataContext as Variable.ValuesListItem; if (listItem == null) { return; } var variable = EditVariableDialog.DataContext as Variable; variable.ValuesList.Remove(listItem); var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); EditVariableDialogValueTxtBox.Text = newValues; } private void InsertListEntryBeforeButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { var listItem = (sender as MenuFlyoutItem)?.DataContext as Variable.ValuesListItem; if (listItem == null) { return; } var variable = EditVariableDialog.DataContext as Variable; var index = variable.ValuesList.IndexOf(listItem); variable.ValuesList.Insert(index, new Variable.ValuesListItem { Text = string.Empty }); var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); EditVariableDialogValueTxtBox.TextChanged -= EditVariableDialogValueTxtBox_TextChanged; EditVariableDialogValueTxtBox.Text = newValues; EditVariableDialogValueTxtBox.TextChanged += EditVariableDialogValueTxtBox_TextChanged; } private void InsertListEntryAfterButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { var listItem = (sender as MenuFlyoutItem)?.DataContext as Variable.ValuesListItem; if (listItem == null) { return; } var variable = EditVariableDialog.DataContext as Variable; var index = variable.ValuesList.IndexOf(listItem); variable.ValuesList.Insert(index + 1, new Variable.ValuesListItem { Text = string.Empty }); var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); EditVariableDialogValueTxtBox.TextChanged -= EditVariableDialogValueTxtBox_TextChanged; EditVariableDialogValueTxtBox.Text = newValues; EditVariableDialogValueTxtBox.TextChanged += EditVariableDialogValueTxtBox_TextChanged; } private void EditVariableValuesListTextBox_LostFocus(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { var listItem = (sender as TextBox)?.DataContext as Variable.ValuesListItem; if (listItem == null) { return; } if (listItem.Text == (sender as TextBox)?.Text) { return; } listItem.Text = (sender as TextBox)?.Text; var variable = EditVariableDialog.DataContext as Variable; var newValues = string.Join(";", variable.ValuesList?.Select(x => x.Text).ToArray()); EditVariableDialogValueTxtBox.TextChanged -= EditVariableDialogValueTxtBox_TextChanged; EditVariableDialogValueTxtBox.Text = newValues; EditVariableDialogValueTxtBox.TextChanged += EditVariableDialogValueTxtBox_TextChanged; } private void InvalidStateInfoBar_CloseButtonClick(InfoBar sender, object args) { ViewModel.EnvironmentState = EnvironmentState.Unchanged; } private void AddVariableFlyout_Closed(object sender, object e) { CancelAddVariable(); ConfirmAddVariableBtn.IsEnabled = false; } } }