[Settings] Fix Quick Accent language list being cropped and not reflowing contents (#45986)

## Summary of the Pull Request
The Character sets list on the Quick Accent settings page had a fixed
3-column layout. This caused two negative user experience issues that
this PR solves:

1. The contents were clipped. When the settings window was resized to be
smaller, the rightmost column(s) were cut off rather than reflowing.
2. The control displayed unnecessary horizontal and vertical scrollbars
nested within the page.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] Closes: #45964
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

I _believe_ the root cause is that the `ItemsWrapGrid` is contained
within the `ListView`'s built-in `ScrollViewer` which was able to expand
infinitely horizontally. During initial layout, the `MaxWidth` binding
to the parent `SettingsGroup`'s `ActualWidth` was respected and the
layout clamped the measurement appropriately, resulting in the correct
number of columns. However, on resize the unbounded `ScrollViewer`'s
infinite horizontal constraint took precedence and the reflow into fewer
columns never happened - the `ScrollViewer` never invalidated its
children's measure because, from its perspective, their available width
(infinite) had not changed. (I think - WinUI's layout and measure cycle
melts my brain.)

The fix required replacing the `MaxWidth` binding on `ItemsWrapGrid`
with a `SizeChanged` handler on the parent `SettingsCard`. The handler
reads the parent card's padding (58 pixels left and 44 pixels right) and
explicitly sets the language set `ListView.MaxWidth` accordingly. A
`Loaded` handler for the card ensures the correct layout on first
render.

The HorizontalScrollbar that caused the layout issue has been removed.

### Screenshots

3-column view:
<img width="1674" height="730" alt="image"
src="https://github.com/user-attachments/assets/890b0f4d-82ef-4147-a220-55941ae5ebc5"
/>


Resized to 2-columns:
<img width="1343" height="730" alt="image"
src="https://github.com/user-attachments/assets/d09aa295-9641-4c19-ab94-597e107614be"
/>

Resized to single-column:
<img width="726" height="823" alt="image"
src="https://github.com/user-attachments/assets/8baa507f-6e03-4f3c-a0ef-2bc2c59ed2e3"
/>


<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

(All manual tests.)

Verified that:
- The 3-column layout is shown when there is enough space (this is the
maximum number of columns because of the page-level constraint.
- The 3-column layout correctly resizes to 2-column then to a
single-column layout when the window is resized, then back again when
made larger.
- The single-column list is shown when the Settings window is opened at
minimum size.
- Selection behaviour performed identically.
This commit is contained in:
Dave Rayment
2026-03-27 09:48:58 +00:00
committed by GitHub
parent df23546c0b
commit ed47bceac2
2 changed files with 41 additions and 9 deletions

View File

@@ -70,7 +70,12 @@
IsThreeState="True" IsThreeState="True"
Unchecked="QuickAccent_SelectedLanguage_UnselectAll" /> Unchecked="QuickAccent_SelectedLanguage_UnselectAll" />
<tkcontrols:SettingsExpander.Items> <tkcontrols:SettingsExpander.Items>
<tkcontrols:SettingsCard> <tkcontrols:SettingsCard
x:Name="LanguageSettingsCard"
HorizontalContentAlignment="Stretch"
ContentAlignment="Left"
Loaded="LanguageSettingsCard_Loaded"
SizeChanged="LanguageSettingsCard_SizeChanged">
<ListView <ListView
x:Name="QuickAccent_Language_Select" x:Name="QuickAccent_Language_Select"
MinWidth="{StaticResource SettingActionControlMinWidth}" MinWidth="{StaticResource SettingActionControlMinWidth}"
@@ -80,22 +85,18 @@
ItemTemplate="{StaticResource LanguageViewTemplate}" ItemTemplate="{StaticResource LanguageViewTemplate}"
ItemsSource="{x:Bind LanguagesCustomViewSource.View, Mode=OneWay}" ItemsSource="{x:Bind LanguagesCustomViewSource.View, Mode=OneWay}"
Loaded="QuickAccent_Language_Select_Loaded" Loaded="QuickAccent_Language_Select_Loaded"
ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollMode="Enabled" ScrollViewer.VerticalScrollMode="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Enabled"
SelectionChanged="QuickAccent_SelectedLanguage_SelectionChanged" SelectionChanged="QuickAccent_SelectedLanguage_SelectionChanged"
SelectionMode="Multiple"> SelectionMode="Multiple">
<ListView.ItemsPanel> <ListView.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<ItemsWrapGrid <ItemsWrapGrid Orientation="Horizontal" />
MaxWidth="{Binding ElementName=QuickAccent_Language, Path=ActualWidth}"
ItemWidth="280"
Orientation="Horizontal" />
</ItemsPanelTemplate> </ItemsPanelTemplate>
</ListView.ItemsPanel> </ListView.ItemsPanel>
<ListView.ItemContainerStyle> <ListView.ItemContainerStyle>
<Style TargetType="ListViewItem"> <Style TargetType="ListViewItem">
<Setter Property="Width" Value="280" />
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="ListViewItem"> <ControlTemplate TargetType="ListViewItem">

View File

@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation // Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license. // The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
using System;
using System.Linq; using System.Linq;
using CommunityToolkit.WinUI; using CommunityToolkit.WinUI;
using Microsoft.PowerToys.Settings.UI.Helpers; using Microsoft.PowerToys.Settings.UI.Helpers;
@@ -91,5 +92,35 @@ namespace Microsoft.PowerToys.Settings.UI.Views
loadingLanguageListDontTriggerSelectionChanged = false; loadingLanguageListDontTriggerSelectionChanged = false;
} }
private void LanguageSettingsCard_Loaded(object sender, RoutedEventArgs e)
{
UpdateLanguageListMaxWidth(sender as Control);
}
private void LanguageSettingsCard_SizeChanged(object sender, SizeChangedEventArgs e)
{
UpdateLanguageListMaxWidth(sender as Control);
}
/// <summary>
/// Constrain the character set lists to the width of the parent card to permit
/// column reflow.
/// </summary>
/// <param name="card">The parent SettingsCard control.</param>
private void UpdateLanguageListMaxWidth(Control card)
{
if (card is null)
{
return;
}
double availableWidth =
card.ActualWidth - card.Padding.Left - card.Padding.Right;
QuickAccent_Language_Select.MaxWidth = Math.Max(
QuickAccent_Language_Select.MinWidth,
availableWidth);
}
} }
} }