Refactor: Extract duplicated boolean-to-visibility converter to shared helper (#44236)

<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

Eliminates code duplication by extracting the `ConvertBoolToVisibility`
method that was duplicated across `MonitorViewModel.cs` and
`MainWindow.xaml.cs` into a shared `VisibilityConverter` helper class.

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

- [ ] **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

**Before:** Identical `ConvertBoolToVisibility` methods existed in two
places for x:Bind visibility conversions.

**After:** Single `VisibilityConverter.BoolToVisibility()` static method
in `Helpers/` namespace.

### Changes
- Created `PowerDisplay.Helpers.VisibilityConverter` with static
`BoolToVisibility` method
- Removed duplicate methods from `MonitorViewModel` and `MainWindow`
- Updated 8 XAML bindings to use
`helpers:VisibilityConverter.BoolToVisibility()`

Maintains AOT-compatible x:Bind pattern while eliminating duplication.

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

Code review and security scan passed with no issues.

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: moooyo <42196638+moooyo@users.noreply.github.com>
This commit is contained in:
Copilot
2025-12-12 14:38:28 +08:00
committed by GitHub
parent 04de4b8357
commit dcf1767c23
4 changed files with 31 additions and 14 deletions

View File

@@ -0,0 +1,22 @@
// 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 Microsoft.UI.Xaml;
namespace PowerDisplay.Helpers
{
/// <summary>
/// Provides conversion utilities for Visibility binding in x:Bind scenarios.
/// AOT-compatible alternative to IValueConverter implementations.
/// </summary>
public static class VisibilityConverter
{
/// <summary>
/// Converts a boolean value to a Visibility value.
/// </summary>
/// <param name="value">The boolean value to convert.</param>
/// <returns>Visibility.Visible if true, Visibility.Collapsed if false.</returns>
public static Visibility BoolToVisibility(bool value) => value ? Visibility.Visible : Visibility.Collapsed;
}
}

View File

@@ -4,6 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:animatedVisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals"
xmlns:animations="using:CommunityToolkit.WinUI.Animations"
xmlns:helpers="using:PowerDisplay.Helpers"
xmlns:local="using:PowerDisplay"
xmlns:models="using:PowerDisplay.Common.Models"
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
@@ -54,7 +55,7 @@
VerticalAlignment="Center"
Orientation="Vertical"
Spacing="16"
Visibility="{x:Bind ConvertBoolToVisibility(ViewModel.IsScanning), Mode=OneWay}">
Visibility="{x:Bind helpers:VisibilityConverter.BoolToVisibility(ViewModel.IsScanning), Mode=OneWay}">
<ProgressRing
Width="24"
Height="24"
@@ -77,7 +78,7 @@
IsClosable="False"
IsOpen="{x:Bind ViewModel.ShowNoMonitorsMessage, Mode=OneWay}"
Severity="Informational"
Visibility="{x:Bind ConvertBoolToVisibility(ViewModel.ShowNoMonitorsMessage), Mode=OneWay}" />
Visibility="{x:Bind helpers:VisibilityConverter.BoolToVisibility(ViewModel.ShowNoMonitorsMessage), Mode=OneWay}" />
<!-- Content Area -->
<ScrollViewer
@@ -93,7 +94,7 @@
x:Name="MonitorsRepeater"
HorizontalAlignment="Stretch"
ItemsSource="{x:Bind ViewModel.Monitors, Mode=OneWay}"
Visibility="{x:Bind ConvertBoolToVisibility(ViewModel.HasMonitors), Mode=OneWay}">
Visibility="{x:Bind helpers:VisibilityConverter.BoolToVisibility(ViewModel.HasMonitors), Mode=OneWay}">
<ItemsRepeater.Layout>
<StackLayout Orientation="Vertical" Spacing="32" />
</ItemsRepeater.Layout>
@@ -123,7 +124,7 @@
Content="{ui:FontIcon Glyph=&#xE712;,
FontSize=16}"
Style="{StaticResource SubtleButtonStyle}"
Visibility="{x:Bind ConvertBoolToVisibility(ShowInputSource), Mode=OneWay}">
Visibility="{x:Bind helpers:VisibilityConverter.BoolToVisibility(ShowInputSource), Mode=OneWay}">
<Button.Flyout>
<Flyout>
<StackPanel Orientation="Vertical">
@@ -200,7 +201,7 @@
<Grid
Margin="0,8,0,0"
HorizontalAlignment="Stretch"
Visibility="{x:Bind ConvertBoolToVisibility(ShowContrast), Mode=OneWay}">
Visibility="{x:Bind helpers:VisibilityConverter.BoolToVisibility(ShowContrast), Mode=OneWay}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="16" />
<ColumnDefinition Width="16" />
@@ -232,7 +233,7 @@
<Grid
Margin="0,8,0,0"
HorizontalAlignment="Stretch"
Visibility="{x:Bind ConvertBoolToVisibility(ShowVolume), Mode=OneWay}">
Visibility="{x:Bind helpers:VisibilityConverter.BoolToVisibility(ShowVolume), Mode=OneWay}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="16" />
<ColumnDefinition Width="16" />
@@ -265,7 +266,7 @@
<Grid
Margin="0,8,0,0"
HorizontalAlignment="Stretch"
Visibility="{x:Bind ConvertBoolToVisibility(ShowRotation), Mode=OneWay}">
Visibility="{x:Bind helpers:VisibilityConverter.BoolToVisibility(ShowRotation), Mode=OneWay}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="16" />
<ColumnDefinition Width="16" />
@@ -363,7 +364,7 @@
Content="{ui:FontIcon Glyph=&#xE748;,
FontSize=16}"
Style="{StaticResource SubtleButtonStyle}"
Visibility="{x:Bind ConvertBoolToVisibility(ViewModel.HasProfiles), Mode=OneWay}">
Visibility="{x:Bind helpers:VisibilityConverter.BoolToVisibility(ViewModel.HasProfiles), Mode=OneWay}">
<Button.Flyout>
<Flyout x:Name="ProfilesFlyout">
<ListView

View File

@@ -37,9 +37,6 @@ namespace PowerDisplay
// Expose ViewModel as property for x:Bind
public MainViewModel ViewModel => _viewModel ?? throw new InvalidOperationException("ViewModel not initialized");
// Conversion functions for x:Bind (AOT-compatible alternative to converters)
public Visibility ConvertBoolToVisibility(bool value) => value ? Visibility.Visible : Visibility.Collapsed;
public MainWindow()
{
try

View File

@@ -219,9 +219,6 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable
}
}
// Conversion function for x:Bind (AOT-compatible alternative to converters)
public Visibility ConvertBoolToVisibility(bool value) => value ? Visibility.Visible : Visibility.Collapsed;
// Property to access IsInteractionEnabled from parent ViewModel
public bool IsInteractionEnabled => _mainViewModel?.IsInteractionEnabled ?? true;