wslsettings: ensure selected setting is auto-expanded and selected (#13689)

* wslsettings: ensure selected setting is auto-selected

Implement keyboard focus management for SettingsExpander controls across settings pages. This resolves an accessibility issue reported internally.

* add asserts

---------

Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
This commit is contained in:
Ben Hillis 2025-11-18 08:19:50 -08:00 committed by GitHub
parent b6cc29eefc
commit 7226b05100
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 112 additions and 22 deletions

View File

@ -1,7 +1,9 @@
// Copyright (C) Microsoft Corporation. All rights reserved. // Copyright (C) Microsoft Corporation. All rights reserved.
using CommunityToolkit.WinUI.Controls;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input; using Microsoft.UI.Xaml.Input;
using System.Diagnostics;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@ -47,4 +49,39 @@ public class RuntimeHelper
FindNextElementOptions fneo = new() { SearchRoot = button.XamlRoot.Content }; FindNextElementOptions fneo = new() { SearchRoot = button.XamlRoot.Content };
FocusManager.TryMoveFocus(FocusNavigationDirection.Previous, fneo); FocusManager.TryMoveFocus(FocusNavigationDirection.Previous, fneo);
} }
public static void SetupSettingsExpanderFocusManagement(Microsoft.UI.Xaml.FrameworkElement expander, Microsoft.UI.Xaml.Controls.Control firstFocusableElement)
{
if (expander is CommunityToolkit.WinUI.Controls.SettingsExpander settingsExpander)
{
settingsExpander.RegisterPropertyChangedCallback(CommunityToolkit.WinUI.Controls.SettingsExpander.IsExpandedProperty, (sender, dp) =>
{
if (sender is CommunityToolkit.WinUI.Controls.SettingsExpander se && se.IsExpanded)
{
System.EventHandler<object>? layoutHandler = null;
layoutHandler = (s, e) =>
{
se.LayoutUpdated -= layoutHandler;
firstFocusableElement.Focus(Microsoft.UI.Xaml.FocusState.Keyboard);
};
se.LayoutUpdated += layoutHandler;
}
});
}
}
public static void SetupExpanderFocusManagementByName(Microsoft.UI.Xaml.FrameworkElement parent, string expanderName, string textBoxName)
{
var expander = parent.FindName(expanderName) as Microsoft.UI.Xaml.FrameworkElement;
var textBox = parent.FindName(textBoxName) as Microsoft.UI.Xaml.Controls.Control;
Debug.Assert(expander != null, $"Expander '{expanderName}' not found");
Debug.Assert(textBox != null, $"TextBox '{textBoxName}' not found");
if (expander != null && textBox != null)
{
SetupSettingsExpanderFocusManagement(expander, textBox);
}
}
} }

View File

@ -25,12 +25,12 @@
<ctControls:SettingsCard x:Uid="Settings_HWPerfCounters"> <ctControls:SettingsCard x:Uid="Settings_HWPerfCounters">
<ToggleSwitch x:Uid="Settings_HWPerfCountersToggleSwitch" HorizontalAlignment="Right" MinWidth="0" IsOn="{x:Bind ViewModel.IsOnHWPerfCounters, Mode=TwoWay}"/> <ToggleSwitch x:Uid="Settings_HWPerfCountersToggleSwitch" HorizontalAlignment="Right" MinWidth="0" IsOn="{x:Bind ViewModel.IsOnHWPerfCounters, Mode=TwoWay}"/>
</ctControls:SettingsCard> </ctControls:SettingsCard>
<ctControls:SettingsExpander x:Uid="Settings_CustomKernelPath"> <ctControls:SettingsExpander x:Name="CustomKernelPathExpander" x:Uid="Settings_CustomKernelPath">
<TextBlock Style="{StaticResource TextBlockFilePathStyle}" Text="{x:Bind ViewModel.CustomKernelPath, Mode=OneWay}"/> <TextBlock Style="{StaticResource TextBlockFilePathStyle}" Text="{x:Bind ViewModel.CustomKernelPath, Mode=OneWay}"/>
<ctControls:SettingsExpander.Items> <ctControls:SettingsExpander.Items>
<ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}"> <ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox x:Uid="Settings_CustomKernelPathTextBox" Style="{StaticResource TextBoxFilePathStyle}" Margin="{StaticResource InputControlSpacingMargin}" <TextBox x:Name="CustomKernelPathTextBox" x:Uid="Settings_CustomKernelPathTextBox" Style="{StaticResource TextBoxFilePathStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Text="{x:Bind ViewModel.CustomKernelPath, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/> Text="{x:Bind ViewModel.CustomKernelPath, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
<Button x:Uid="Settings_CustomKernelPathBrowseButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <Button x:Uid="Settings_CustomKernelPathBrowseButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Click="CustomKernelPath_Click"/> Click="CustomKernelPath_Click"/>
@ -38,12 +38,12 @@
</ctControls:SettingsCard> </ctControls:SettingsCard>
</ctControls:SettingsExpander.Items> </ctControls:SettingsExpander.Items>
</ctControls:SettingsExpander> </ctControls:SettingsExpander>
<ctControls:SettingsExpander x:Uid="Settings_CustomKernelModulesPath"> <ctControls:SettingsExpander x:Name="CustomKernelModulesPathExpander" x:Uid="Settings_CustomKernelModulesPath">
<TextBlock Style="{StaticResource TextBlockFilePathStyle}" Text="{x:Bind ViewModel.CustomKernelModulesPath, Mode=OneWay}"/> <TextBlock Style="{StaticResource TextBlockFilePathStyle}" Text="{x:Bind ViewModel.CustomKernelModulesPath, Mode=OneWay}"/>
<ctControls:SettingsExpander.Items> <ctControls:SettingsExpander.Items>
<ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}"> <ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox x:Uid="Settings_CustomKernelModulesPathTextBox" Style="{StaticResource TextBoxFilePathStyle}" Margin="{StaticResource InputControlSpacingMargin}" <TextBox x:Name="CustomKernelModulesPathTextBox" x:Uid="Settings_CustomKernelModulesPathTextBox" Style="{StaticResource TextBoxFilePathStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Text="{x:Bind ViewModel.CustomKernelModulesPath, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/> Text="{x:Bind ViewModel.CustomKernelModulesPath, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
<Button x:Uid="Settings_CustomKernelModulesPathBrowseButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <Button x:Uid="Settings_CustomKernelModulesPathBrowseButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Click="CustomKernelModulesPath_Click"/> Click="CustomKernelModulesPath_Click"/>
@ -51,7 +51,7 @@
</ctControls:SettingsCard> </ctControls:SettingsCard>
</ctControls:SettingsExpander.Items> </ctControls:SettingsExpander.Items>
</ctControls:SettingsExpander> </ctControls:SettingsExpander>
<ctControls:SettingsExpander x:Uid="Settings_CustomSystemDistroPath"> <ctControls:SettingsExpander x:Name="CustomSystemDistroPathExpander" x:Uid="Settings_CustomSystemDistroPath">
<ctControls:SettingsExpander.Description> <ctControls:SettingsExpander.Description>
<controls:HyperlinkTextBlock x:Uid="Settings_CustomSystemDistroPathDescription"/> <controls:HyperlinkTextBlock x:Uid="Settings_CustomSystemDistroPathDescription"/>
</ctControls:SettingsExpander.Description> </ctControls:SettingsExpander.Description>
@ -59,7 +59,7 @@
<ctControls:SettingsExpander.Items> <ctControls:SettingsExpander.Items>
<ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}"> <ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox x:Uid="Settings_CustomSystemDistroPathTextBox" Style="{StaticResource TextBoxFilePathStyle}" Margin="{StaticResource InputControlSpacingMargin}" <TextBox x:Name="CustomSystemDistroPathTextBox" x:Uid="Settings_CustomSystemDistroPathTextBox" Style="{StaticResource TextBoxFilePathStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Text="{x:Bind ViewModel.CustomSystemDistroPath, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/> Text="{x:Bind ViewModel.CustomSystemDistroPath, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
<Button x:Uid="Settings_CustomSystemDistroPathBrowseButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <Button x:Uid="Settings_CustomSystemDistroPathBrowseButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Click="CustomSystemDistroPath_Click"/> Click="CustomSystemDistroPath_Click"/>

View File

@ -27,6 +27,15 @@ public sealed partial class DeveloperPage : Page
FrameworkElementAutomationPeer.FromElement(Settings_ErrorTryAgainLater).RaiseAutomationEvent(AutomationEvents.LiveRegionChanged); FrameworkElementAutomationPeer.FromElement(Settings_ErrorTryAgainLater).RaiseAutomationEvent(AutomationEvents.LiveRegionChanged);
} }
}); });
this.Loaded += OnPageLoaded;
}
private void OnPageLoaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
RuntimeHelper.SetupExpanderFocusManagementByName(this, "CustomKernelPathExpander", "CustomKernelPathTextBox");
RuntimeHelper.SetupExpanderFocusManagementByName(this, "CustomKernelModulesPathExpander", "CustomKernelModulesPathTextBox");
RuntimeHelper.SetupExpanderFocusManagementByName(this, "CustomSystemDistroPathExpander", "CustomSystemDistroPathTextBox");
} }
override protected void OnNavigatedFrom(NavigationEventArgs e) override protected void OnNavigatedFrom(NavigationEventArgs e)

View File

@ -18,12 +18,12 @@
<ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto" <ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto"
Visibility="{x:Bind ViewModel.SettingsContentVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToVisibilityConverter}}"> Visibility="{x:Bind ViewModel.SettingsContentVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}"> <StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<ctControls:SettingsExpander x:Uid="Settings_DefaultVHDSize"> <ctControls:SettingsExpander x:Name="DefaultVHDSizeExpander" x:Uid="Settings_DefaultVHDSize">
<TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.DefaultVHDSize, Mode=OneWay, Converter={StaticResource MegabyteStringConverter}}"/> <TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.DefaultVHDSize, Mode=OneWay, Converter={StaticResource MegabyteStringConverter}}"/>
<ctControls:SettingsExpander.Items> <ctControls:SettingsExpander.Items>
<ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}"> <ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox x:Uid="Settings_DefaultVHDSizeTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <TextBox x:Name="DefaultVHDSizeTextBox" x:Uid="Settings_DefaultVHDSizeTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Text="{x:Bind ViewModel.DefaultVHDSize, Mode=TwoWay, UpdateSourceTrigger=LostFocus, Converter={StaticResource MegabyteNumberConverter}}" TextChanged="DefaultVHDSizeTextBox_TextChanged"/> Text="{x:Bind ViewModel.DefaultVHDSize, Mode=TwoWay, UpdateSourceTrigger=LostFocus, Converter={StaticResource MegabyteNumberConverter}}" TextChanged="DefaultVHDSizeTextBox_TextChanged"/>
<Button x:Uid="Settings_DefaultVHDSizeResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <Button x:Uid="Settings_DefaultVHDSizeResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Command="{x:Bind ViewModel.DefaultVHDSize_ResetCommand}" IsEnabled="{x:Bind ViewModel.DefaultVHDSize_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Command="{x:Bind ViewModel.DefaultVHDSize_ResetCommand}" IsEnabled="{x:Bind ViewModel.DefaultVHDSize_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

View File

@ -1,8 +1,10 @@
// Copyright (C) Microsoft Corporation. All rights reserved. // Copyright (C) Microsoft Corporation. All rights reserved.
using CommunityToolkit.WinUI.Controls;
using Microsoft.UI.Xaml.Automation.Peers; using Microsoft.UI.Xaml.Automation.Peers;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Navigation; using Microsoft.UI.Xaml.Navigation;
using System.Diagnostics;
using WslSettings.Contracts.Services; using WslSettings.Contracts.Services;
using WslSettings.ViewModels.Settings; using WslSettings.ViewModels.Settings;
@ -26,6 +28,8 @@ public sealed partial class FileSystemPage : Page
FrameworkElementAutomationPeer.FromElement(Settings_ErrorTryAgainLater).RaiseAutomationEvent(AutomationEvents.LiveRegionChanged); FrameworkElementAutomationPeer.FromElement(Settings_ErrorTryAgainLater).RaiseAutomationEvent(AutomationEvents.LiveRegionChanged);
} }
}); });
this.Loaded += OnPageLoaded;
} }
override protected void OnNavigatedFrom(NavigationEventArgs e) override protected void OnNavigatedFrom(NavigationEventArgs e)
@ -53,4 +57,18 @@ public sealed partial class FileSystemPage : Page
TextBox? textBox = sender as TextBox; TextBox? textBox = sender as TextBox;
ViewModel.SetDefaultVHDSize_ResetEnabled(textBox!.Text); ViewModel.SetDefaultVHDSize_ResetEnabled(textBox!.Text);
} }
private void OnPageLoaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
var expander = this.FindName("DefaultVHDSizeExpander") as SettingsExpander;
var textBox = this.FindName("DefaultVHDSizeTextBox") as TextBox;
Debug.Assert(expander != null, "DefaultVHDSizeExpander not found");
Debug.Assert(textBox != null, "DefaultVHDSizeTextBox not found");
if (expander != null && textBox != null)
{
RuntimeHelper.SetupSettingsExpanderFocusManagement(expander, textBox);
}
}
} }

View File

@ -18,12 +18,12 @@
<ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto" <ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto"
Visibility="{x:Bind ViewModel.SettingsContentVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToVisibilityConverter}}"> Visibility="{x:Bind ViewModel.SettingsContentVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}"> <StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<ctControls:SettingsExpander x:Uid="Settings_ProcCount"> <ctControls:SettingsExpander x:Name="ProcCountExpander" x:Uid="Settings_ProcCount">
<TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.ProcCount, Mode=OneWay}"/> <TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.ProcCount, Mode=OneWay}"/>
<ctControls:SettingsExpander.Items> <ctControls:SettingsExpander.Items>
<ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}"> <ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox x:Uid="Settings_ProcCountTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <TextBox x:Name="ProcCountTextBox" x:Uid="Settings_ProcCountTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Text="{x:Bind ViewModel.ProcCount, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" TextChanged="ProcCountTextBox_TextChanged"/> Text="{x:Bind ViewModel.ProcCount, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" TextChanged="ProcCountTextBox_TextChanged"/>
<Button x:Uid="Settings_ProcCountResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <Button x:Uid="Settings_ProcCountResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Command="{x:Bind ViewModel.ProcCount_ResetCommand}" IsEnabled="{x:Bind ViewModel.ProcCount_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Command="{x:Bind ViewModel.ProcCount_ResetCommand}" IsEnabled="{x:Bind ViewModel.ProcCount_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
@ -32,12 +32,12 @@
</ctControls:SettingsCard> </ctControls:SettingsCard>
</ctControls:SettingsExpander.Items> </ctControls:SettingsExpander.Items>
</ctControls:SettingsExpander> </ctControls:SettingsExpander>
<ctControls:SettingsExpander x:Uid="Settings_MemorySize"> <ctControls:SettingsExpander x:Name="MemorySizeExpander" x:Uid="Settings_MemorySize">
<TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.MemorySize, Mode=OneWay, Converter={StaticResource MegabyteStringConverter}}"/> <TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.MemorySize, Mode=OneWay, Converter={StaticResource MegabyteStringConverter}}"/>
<ctControls:SettingsExpander.Items> <ctControls:SettingsExpander.Items>
<ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}"> <ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox x:Uid="Settings_MemorySizeTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <TextBox x:Name="MemorySizeTextBox" x:Uid="Settings_MemorySizeTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Text="{x:Bind ViewModel.MemorySize, Mode=TwoWay, UpdateSourceTrigger=LostFocus, Converter={StaticResource MegabyteNumberConverter}}" TextChanged="MemorySizeTextBox_TextChanged"/> Text="{x:Bind ViewModel.MemorySize, Mode=TwoWay, UpdateSourceTrigger=LostFocus, Converter={StaticResource MegabyteNumberConverter}}" TextChanged="MemorySizeTextBox_TextChanged"/>
<Button x:Uid="Settings_MemorySizeResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <Button x:Uid="Settings_MemorySizeResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Command="{x:Bind ViewModel.MemorySize_ResetCommand}" IsEnabled="{x:Bind ViewModel.MemorySize_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Command="{x:Bind ViewModel.MemorySize_ResetCommand}" IsEnabled="{x:Bind ViewModel.MemorySize_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
@ -46,12 +46,12 @@
</ctControls:SettingsCard> </ctControls:SettingsCard>
</ctControls:SettingsExpander.Items> </ctControls:SettingsExpander.Items>
</ctControls:SettingsExpander> </ctControls:SettingsExpander>
<ctControls:SettingsExpander x:Uid="Settings_SwapSize"> <ctControls:SettingsExpander x:Name="SwapSizeExpander" x:Uid="Settings_SwapSize">
<TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.SwapSize, Mode=OneWay, Converter={StaticResource MegabyteStringConverter}}"/> <TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.SwapSize, Mode=OneWay, Converter={StaticResource MegabyteStringConverter}}"/>
<ctControls:SettingsExpander.Items> <ctControls:SettingsExpander.Items>
<ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}"> <ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox x:Uid="Settings_SwapSizeTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <TextBox x:Name="SwapSizeTextBox" x:Uid="Settings_SwapSizeTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Text="{x:Bind ViewModel.SwapSize, Mode=TwoWay, UpdateSourceTrigger=LostFocus, Converter={StaticResource MegabyteNumberConverter}}" TextChanged="SwapSizeTextBox_TextChanged"/> Text="{x:Bind ViewModel.SwapSize, Mode=TwoWay, UpdateSourceTrigger=LostFocus, Converter={StaticResource MegabyteNumberConverter}}" TextChanged="SwapSizeTextBox_TextChanged"/>
<Button x:Uid="Settings_SwapSizeResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <Button x:Uid="Settings_SwapSizeResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Command="{x:Bind ViewModel.SwapSize_ResetCommand}" IsEnabled="{x:Bind ViewModel.SwapSize_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Command="{x:Bind ViewModel.SwapSize_ResetCommand}" IsEnabled="{x:Bind ViewModel.SwapSize_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
@ -60,12 +60,12 @@
</ctControls:SettingsCard> </ctControls:SettingsCard>
</ctControls:SettingsExpander.Items> </ctControls:SettingsExpander.Items>
</ctControls:SettingsExpander> </ctControls:SettingsExpander>
<ctControls:SettingsExpander x:Uid="Settings_SwapFilePath"> <ctControls:SettingsExpander x:Name="SwapFilePathExpander" x:Uid="Settings_SwapFilePath">
<TextBlock Style="{StaticResource TextBlockFilePathStyle}" Text="{x:Bind ViewModel.SwapFilePath, Mode=OneWay}"/> <TextBlock Style="{StaticResource TextBlockFilePathStyle}" Text="{x:Bind ViewModel.SwapFilePath, Mode=OneWay}"/>
<ctControls:SettingsExpander.Items> <ctControls:SettingsExpander.Items>
<ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}"> <ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox x:Uid="Settings_SwapFilePathTextBox" Style="{StaticResource TextBoxFilePathStyle}" Margin="{StaticResource InputControlSpacingMargin}" <TextBox x:Name="SwapFilePathTextBox" x:Uid="Settings_SwapFilePathTextBox" Style="{StaticResource TextBoxFilePathStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Text="{x:Bind ViewModel.SwapFilePath, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/> Text="{x:Bind ViewModel.SwapFilePath, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
<Button x:Uid="Settings_SwapFilePathBrowseButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <Button x:Uid="Settings_SwapFilePathBrowseButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Click="SwapFilePath_Click"/> Click="SwapFilePath_Click"/>

View File

@ -27,6 +27,16 @@ public sealed partial class MemAndProcPage : Page
FrameworkElementAutomationPeer.FromElement(Settings_ErrorTryAgainLater).RaiseAutomationEvent(AutomationEvents.LiveRegionChanged); FrameworkElementAutomationPeer.FromElement(Settings_ErrorTryAgainLater).RaiseAutomationEvent(AutomationEvents.LiveRegionChanged);
} }
}); });
this.Loaded += OnPageLoaded;
}
private void OnPageLoaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
RuntimeHelper.SetupExpanderFocusManagementByName(this, "ProcCountExpander", "ProcCountTextBox");
RuntimeHelper.SetupExpanderFocusManagementByName(this, "MemorySizeExpander", "MemorySizeTextBox");
RuntimeHelper.SetupExpanderFocusManagementByName(this, "SwapSizeExpander", "SwapSizeTextBox");
RuntimeHelper.SetupExpanderFocusManagementByName(this, "SwapFilePathExpander", "SwapFilePathTextBox");
} }
override protected void OnNavigatedFrom(NavigationEventArgs e) override protected void OnNavigatedFrom(NavigationEventArgs e)

View File

@ -25,12 +25,12 @@
<ctControls:SettingsCard x:Uid="Settings_HyperVFirewall"> <ctControls:SettingsCard x:Uid="Settings_HyperVFirewall">
<ToggleSwitch x:Uid="Settings_HyperVFirewallToggleSwitch" HorizontalAlignment="Right" MinWidth="0" IsOn="{x:Bind ViewModel.IsOnHyperVFirewall, Mode=TwoWay}"/> <ToggleSwitch x:Uid="Settings_HyperVFirewallToggleSwitch" HorizontalAlignment="Right" MinWidth="0" IsOn="{x:Bind ViewModel.IsOnHyperVFirewall, Mode=TwoWay}"/>
</ctControls:SettingsCard> </ctControls:SettingsCard>
<ctControls:SettingsExpander x:Uid="Settings_IgnoredPorts"> <ctControls:SettingsExpander x:Name="IgnoredPortsExpander" x:Uid="Settings_IgnoredPorts">
<TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.IgnoredPorts, Mode=OneWay}"/> <TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.IgnoredPorts, Mode=OneWay}"/>
<ctControls:SettingsExpander.Items> <ctControls:SettingsExpander.Items>
<ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}"> <ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox x:Uid="Settings_IgnoredPortsTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <TextBox x:Name="IgnoredPortsTextBox" x:Uid="Settings_IgnoredPortsTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Text="{x:Bind ViewModel.IgnoredPorts, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/> Text="{x:Bind ViewModel.IgnoredPorts, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
<Button x:Uid="Settings_IgnoredPortsResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <Button x:Uid="Settings_IgnoredPortsResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Command="{x:Bind ViewModel.IgnoredPorts_ResetCommand}" IsEnabled="{x:Bind ViewModel.IgnoredPorts_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Command="{x:Bind ViewModel.IgnoredPorts_ResetCommand}" IsEnabled="{x:Bind ViewModel.IgnoredPorts_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
@ -48,12 +48,12 @@
<ctControls:SettingsCard x:Uid="Settings_AutoProxy"> <ctControls:SettingsCard x:Uid="Settings_AutoProxy">
<ToggleSwitch x:Uid="Settings_AutoProxyToggleSwitch" HorizontalAlignment="Right" MinWidth="0" IsOn="{x:Bind ViewModel.IsOnAutoProxy, Mode=TwoWay}"/> <ToggleSwitch x:Uid="Settings_AutoProxyToggleSwitch" HorizontalAlignment="Right" MinWidth="0" IsOn="{x:Bind ViewModel.IsOnAutoProxy, Mode=TwoWay}"/>
</ctControls:SettingsCard> </ctControls:SettingsCard>
<ctControls:SettingsExpander x:Uid="Settings_InitialAutoProxyTimeout"> <ctControls:SettingsExpander x:Name="InitialAutoProxyTimeoutExpander" x:Uid="Settings_InitialAutoProxyTimeout">
<TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.InitialAutoProxyTimeout, Mode=OneWay, Converter={StaticResource MillisecondsStringConverter}}"/> <TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.InitialAutoProxyTimeout, Mode=OneWay, Converter={StaticResource MillisecondsStringConverter}}"/>
<ctControls:SettingsExpander.Items> <ctControls:SettingsExpander.Items>
<ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}"> <ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox x:Uid="Settings_InitialAutoProxyTimeoutTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <TextBox x:Name="InitialAutoProxyTimeoutTextBox" x:Uid="Settings_InitialAutoProxyTimeoutTextBox" Style="{StaticResource TextBoxSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Text="{x:Bind ViewModel.InitialAutoProxyTimeout, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" TextChanged="InitialAutoProxyTimeoutTextBox_TextChanged"/> Text="{x:Bind ViewModel.InitialAutoProxyTimeout, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" TextChanged="InitialAutoProxyTimeoutTextBox_TextChanged"/>
<Button x:Uid="Settings_InitialAutoProxyTimeoutResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <Button x:Uid="Settings_InitialAutoProxyTimeoutResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Command="{x:Bind ViewModel.InitialAutoProxyTimeout_ResetCommand}" IsEnabled="{x:Bind ViewModel.InitialAutoProxyTimeout_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Command="{x:Bind ViewModel.InitialAutoProxyTimeout_ResetCommand}" IsEnabled="{x:Bind ViewModel.InitialAutoProxyTimeout_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

View File

@ -26,6 +26,14 @@ public sealed partial class NetworkingPage : Page
FrameworkElementAutomationPeer.FromElement(Settings_ErrorTryAgainLater).RaiseAutomationEvent(AutomationEvents.LiveRegionChanged); FrameworkElementAutomationPeer.FromElement(Settings_ErrorTryAgainLater).RaiseAutomationEvent(AutomationEvents.LiveRegionChanged);
} }
}); });
this.Loaded += OnPageLoaded;
}
private void OnPageLoaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
RuntimeHelper.SetupExpanderFocusManagementByName(this, "IgnoredPortsExpander", "IgnoredPortsTextBox");
RuntimeHelper.SetupExpanderFocusManagementByName(this, "InitialAutoProxyTimeoutExpander", "InitialAutoProxyTimeoutTextBox");
} }
override protected void OnNavigatedFrom(NavigationEventArgs e) override protected void OnNavigatedFrom(NavigationEventArgs e)

View File

@ -38,12 +38,12 @@
<ctControls:SettingsCard x:Uid="Settings_SparseVHD"> <ctControls:SettingsCard x:Uid="Settings_SparseVHD">
<ToggleSwitch x:Uid="Settings_SparseVHDToggleSwitch" HorizontalAlignment="Right" MinWidth="0" IsOn="{x:Bind ViewModel.IsOnSparseVHD, Mode=TwoWay}"/> <ToggleSwitch x:Uid="Settings_SparseVHDToggleSwitch" HorizontalAlignment="Right" MinWidth="0" IsOn="{x:Bind ViewModel.IsOnSparseVHD, Mode=TwoWay}"/>
</ctControls:SettingsCard> </ctControls:SettingsCard>
<ctControls:SettingsExpander x:Uid="Settings_VMIdleTimeout"> <ctControls:SettingsExpander x:Name="VMIdleTimeoutExpander" x:Uid="Settings_VMIdleTimeout">
<TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.VMIdleTimeout, Mode=OneWay, Converter={StaticResource MillisecondsStringConverter}}"/> <TextBlock Style="{StaticResource TextBlockSettingStyle}" Text="{x:Bind ViewModel.VMIdleTimeout, Mode=OneWay, Converter={StaticResource MillisecondsStringConverter}}"/>
<ctControls:SettingsExpander.Items> <ctControls:SettingsExpander.Items>
<ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}"> <ctControls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left" Margin="{StaticResource SettingsExpanderItemMargin}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox x:Uid="Settings_VMIdleTimeoutTextBox" Style="{StaticResource TextBoxFilePathStyle}" Margin="{StaticResource InputControlSpacingMargin}" <TextBox x:Name="VMIdleTimeoutTextBox" x:Uid="Settings_VMIdleTimeoutTextBox" Style="{StaticResource TextBoxFilePathStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Text="{x:Bind ViewModel.VMIdleTimeout, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" TextChanged="VMIdleTimeoutTextBox_TextChanged"/> Text="{x:Bind ViewModel.VMIdleTimeout, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" TextChanged="VMIdleTimeoutTextBox_TextChanged"/>
<Button x:Uid="Settings_VMIdleTimeoutResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}" <Button x:Uid="Settings_VMIdleTimeoutResetButton" Style="{StaticResource ButtonSettingStyle}" Margin="{StaticResource InputControlSpacingMargin}"
Command="{x:Bind ViewModel.VMIdleTimeout_ResetCommand}" IsEnabled="{x:Bind ViewModel.VMIdleTimeout_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Command="{x:Bind ViewModel.VMIdleTimeout_ResetCommand}" IsEnabled="{x:Bind ViewModel.VMIdleTimeout_ResetEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

View File

@ -26,6 +26,14 @@ public sealed partial class OptionalFeaturesPage : Page
FrameworkElementAutomationPeer.FromElement(Settings_ErrorTryAgainLater).RaiseAutomationEvent(AutomationEvents.LiveRegionChanged); FrameworkElementAutomationPeer.FromElement(Settings_ErrorTryAgainLater).RaiseAutomationEvent(AutomationEvents.LiveRegionChanged);
} }
}); });
this.Loaded += OnPageLoaded;
}
private void OnPageLoaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
RuntimeHelper.SetupExpanderFocusManagementByName(this, "SystemdSettingsExpander", "InitTextBox");
RuntimeHelper.SetupExpanderFocusManagementByName(this, "VMIdleTimeoutExpander", "VMIdleTimeoutTextBox");
} }
override protected void OnNavigatedFrom(NavigationEventArgs e) override protected void OnNavigatedFrom(NavigationEventArgs e)