Skip to content

[WIP] Analyze effort for adding segmented control for Windows platform - #23

Draft
yurkinh with Copilot wants to merge 5 commits into
mainfrom
copilot/analyze-segmented-control-effort
Draft

[WIP] Analyze effort for adding segmented control for Windows platform#23
yurkinh with Copilot wants to merge 5 commits into
mainfrom
copilot/analyze-segmented-control-effort

Conversation

Copilot AI commented Feb 20, 2026

Copy link
Copy Markdown
Contributor
  • Explore repository structure and understand existing platform implementations
  • Understand Community Toolkit Windows Segmented control source code
  • Extract Community Toolkit Segmented C# classes into Platforms/Windows/NativeSegmented/
  • Create simplified WinUI3 XAML styles Platforms/Windows/Themes/SegmentedStyles.xaml
  • Rewrite Platforms/Windows/SegmentedControlHandler.cs to use the extracted Segmented control
  • Update AppHostBuilderExtensions to load WinUI3 resource dictionary on Windows
  • Update csproj to add Windows target framework and Page build action for XAML
  • Update sample project for Windows
  • Build verified (C# compiles cleanly on Linux cross-compile; XAML compilation requires Windows)
  • Code review completed and feedback addressed
  • Security scan: 0 alerts
  • Fix: DisabledBackgroundColorButtonItemBackgroundDisabled (unselected disabled segment bg); DisabledTintColor → border/outline when disabled; MapIsEnabled now toggles border between TintColor/DisabledTintColor
  • Fix: Add cached brush fields to SegmentedControlHandler to avoid per-update allocations
  • Fix: Added EnableWindowsTargeting=true so non-Windows CI hosts can compile the Windows TFM (TFM itself was already made unconditional in prior commit)

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: yurkinh <17849938+yurkinh@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR is a WIP step toward adding Windows support to Plugin.Maui.SegmentedControl, by introducing a Windows target framework and a first WinUI-based handler implementation, plus aligning the sample project’s Windows platform version settings.

Changes:

  • Add a Windows target framework (net10.0-windows10.0.19041.0) and Windows platform min/version properties to the plugin project.
  • Introduce a Windows SegmentedControlHandler implemented with WinUI Grid + Buttons.
  • Enable Windows SupportedOSPlatformVersion / TargetPlatformMinVersion settings in the sample project.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/Plugin.Maui.SegmentedControl/Plugin.Maui.SegmentedControl.csproj Adds conditional Windows TFM and Windows platform version settings; includes Windows platform folder items.
src/Plugin.Maui.SegmentedControl/Platforms/Windows/SegmentedControlHandler.cs New WinUI handler implementing segment rendering and interaction for Windows.
samples/SegmentedControlSamples/SegmentedControlSamples.csproj Enables Windows supported/min platform versions for the sample app.

Comment thread src/Plugin.Maui.SegmentedControl/Platforms/Windows/SegmentedControlHandler.cs Outdated
Comment thread src/Plugin.Maui.SegmentedControl/Platforms/Windows/SegmentedControlHandler.cs Outdated
Comment thread src/Plugin.Maui.SegmentedControl/Plugin.Maui.SegmentedControl.csproj Outdated
…Segmented control

Co-authored-by: yurkinh <17849938+yurkinh@users.noreply.github.com>
yurkinh and others added 2 commits February 20, 2026 17:19
…csproj

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…che brushes, always include Windows TFM

Co-authored-by: yurkinh <17849938+yurkinh@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Comment on lines +96 to +129
ResourceKey="SystemColorButtonFaceColor" />
<StaticResource x:Key="SegmentedBorderBrush"
ResourceKey="SystemColorHighlightColorBrush" />
<Thickness x:Key="SegmentedBorderThickness">1</Thickness>

<StaticResource x:Key="ButtonItemBackground"
ResourceKey="SystemColorButtonFaceColor" />
<StaticResource x:Key="ButtonItemBackgroundPointerOver"
ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="ButtonItemBackgroundPressed"
ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="ButtonItemBackgroundSelected"
ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="ButtonItemBackgroundSelectedPointerOver"
ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="ButtonItemBackgroundSelectedPressed"
ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="ButtonItemBackgroundDisabled"
ResourceKey="SystemColorButtonFaceColor" />

<StaticResource x:Key="ButtonItemForeground"
ResourceKey="SystemColorButtonTextColor" />
<StaticResource x:Key="ButtonItemForegroundPointerOver"
ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="ButtonItemForegroundPressed"
ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="ButtonItemForegroundSelected"
ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="ButtonItemForegroundSelectedPointerOver"
ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="ButtonItemForegroundSelectedPressed"
ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="ButtonItemForegroundDisabled"
ResourceKey="SystemColorGrayTextColor" />

Copilot AI Feb 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HighContrast theme dictionary aliases SystemColor*Color resources (eg SystemColorHighlightColor, SystemColorButtonFaceColor, SystemColorButtonTextColor) into keys that are later used for Background/Foreground (Brush) properties. In WinUI these *Color resources are Color values (not Brush), which can cause XAML type conversion/runtime failures. Use the corresponding *Brush resources (eg SystemColorHighlightColorBrush, SystemColorButtonFaceColorBrush, SystemColorButtonTextColorBrush, etc.) for brush-valued keys.

Suggested change
ResourceKey="SystemColorButtonFaceColor" />
<StaticResource x:Key="SegmentedBorderBrush"
ResourceKey="SystemColorHighlightColorBrush" />
<Thickness x:Key="SegmentedBorderThickness">1</Thickness>
<StaticResource x:Key="ButtonItemBackground"
ResourceKey="SystemColorButtonFaceColor" />
<StaticResource x:Key="ButtonItemBackgroundPointerOver"
ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="ButtonItemBackgroundPressed"
ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="ButtonItemBackgroundSelected"
ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="ButtonItemBackgroundSelectedPointerOver"
ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="ButtonItemBackgroundSelectedPressed"
ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="ButtonItemBackgroundDisabled"
ResourceKey="SystemColorButtonFaceColor" />
<StaticResource x:Key="ButtonItemForeground"
ResourceKey="SystemColorButtonTextColor" />
<StaticResource x:Key="ButtonItemForegroundPointerOver"
ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="ButtonItemForegroundPressed"
ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="ButtonItemForegroundSelected"
ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="ButtonItemForegroundSelectedPointerOver"
ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="ButtonItemForegroundSelectedPressed"
ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="ButtonItemForegroundDisabled"
ResourceKey="SystemColorGrayTextColor" />
ResourceKey="SystemColorButtonFaceColorBrush" />
<StaticResource x:Key="SegmentedBorderBrush"
ResourceKey="SystemColorHighlightColorBrush" />
<Thickness x:Key="SegmentedBorderThickness">1</Thickness>
<StaticResource x:Key="ButtonItemBackground"
ResourceKey="SystemColorButtonFaceColorBrush" />
<StaticResource x:Key="ButtonItemBackgroundPointerOver"
ResourceKey="SystemColorHighlightColorBrush" />
<StaticResource x:Key="ButtonItemBackgroundPressed"
ResourceKey="SystemColorHighlightColorBrush" />
<StaticResource x:Key="ButtonItemBackgroundSelected"
ResourceKey="SystemColorHighlightColorBrush" />
<StaticResource x:Key="ButtonItemBackgroundSelectedPointerOver"
ResourceKey="SystemColorHighlightColorBrush" />
<StaticResource x:Key="ButtonItemBackgroundSelectedPressed"
ResourceKey="SystemColorHighlightColorBrush" />
<StaticResource x:Key="ButtonItemBackgroundDisabled"
ResourceKey="SystemColorButtonFaceColorBrush" />
<StaticResource x:Key="ButtonItemForeground"
ResourceKey="SystemColorButtonTextColorBrush" />
<StaticResource x:Key="ButtonItemForegroundPointerOver"
ResourceKey="SystemColorHighlightTextColorBrush" />
<StaticResource x:Key="ButtonItemForegroundPressed"
ResourceKey="SystemColorHighlightTextColorBrush" />
<StaticResource x:Key="ButtonItemForegroundSelected"
ResourceKey="SystemColorHighlightTextColorBrush" />
<StaticResource x:Key="ButtonItemForegroundSelectedPointerOver"
ResourceKey="SystemColorHighlightTextColorBrush" />
<StaticResource x:Key="ButtonItemForegroundSelectedPressed"
ResourceKey="SystemColorHighlightTextColorBrush" />
<StaticResource x:Key="ButtonItemForegroundDisabled"
ResourceKey="SystemColorGrayTextColorBrush" />

Copilot uses AI. Check for mistakes.
Comment on lines +261 to +269
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled" />
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PART_Root"
Storyboard.TargetProperty="Opacity"
To="{ThemeResource SegmentedItemDisabledOpacity}"
Duration="0:0:0.083" />
</Storyboard>

Copilot AI Feb 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The template uses a separate DisabledStates group (Enabled/Disabled) and the Disabled state only animates opacity. Control/ListViewItem commonly drives IsEnabled via a Disabled state inside CommonStates, so this group may not be entered automatically, and even if it is entered the handler-provided ButtonItemBackgroundDisabled/ButtonItemForegroundDisabled brushes aren’t applied anywhere. Consider handling disabled in CommonStates (or in code) and explicitly setting Background/Foreground to the disabled theme resources so DisabledBackgroundColor/DisabledTextColor take effect.

Copilot uses AI. Check for mistakes.
Comment on lines +89 to +91
var currentItem = ItemFromContainer(currentContainerItem);
var previousIndex = Items.IndexOf(currentItem);
var index = Math.Clamp(previousIndex + adjustment, 0, Items.Count);

Copilot AI Feb 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In MoveFocus, the clamped upper bound uses Items.Count, which allows index == Items.Count and guarantees ContainerFromIndex(index) returns null. This breaks keyboard navigation when moving past the last item (and can also prevent moving focus to the last item in some cases). Clamp to Items.Count - 1 (and handle the empty-items case) so the computed index is always a valid item index.

Suggested change
var currentItem = ItemFromContainer(currentContainerItem);
var previousIndex = Items.IndexOf(currentItem);
var index = Math.Clamp(previousIndex + adjustment, 0, Items.Count);
if (Items.Count is 0)
{
return false;
}
var currentItem = ItemFromContainer(currentContainerItem);
var previousIndex = Items.IndexOf(currentItem);
var index = Math.Clamp(previousIndex + adjustment, 0, Items.Count - 1);

Copilot uses AI. Check for mistakes.
Comment on lines +69 to +80
void UpdateVisualStates()
{
string contentState = (Icon is null, Content is null) switch
{
(false, false) => _isVertical ? IconTopState : IconLeftState,
(false, true) => IconOnlyState,
(true, false) => ContentOnlyState,
_ => ContentOnlyState,
};

Microsoft.UI.Xaml.VisualStateManager.GoToState(this, contentState, true);
Microsoft.UI.Xaml.VisualStateManager.GoToState(this, _isVertical ? VerticalState : HorizontalState, true);

Copilot AI Feb 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UpdateVisualStates() transitions to IconTop, Horizontal, and Vertical states, but the provided WinUI template in SegmentedStyles.xaml only defines IconLeft, IconOnly, and ContentOnly (and no orientation states). As a result, GoToState will fail for those missing states and vertical-orientation/icon+content layout won’t work. Either add the missing VisualStates to the template or remove/adjust the unreachable states in code to match the simplified template.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants