Skip to content

Fix DatePicker CharacterSpacing property not working on Windows platform #30139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Jun 23, 2025

Description

The CharacterSpacing property on DatePicker was not working on the Windows platform. While this property worked correctly on other platforms like Android and iOS, it had no visible effect on Windows.

Root Cause

The issue occurred because:

  • On Android: MauiDatePicker inherits from AppCompatEditText (which extends TextView), so it automatically gets the CharacterSpacing property support through existing TextViewExtensions.UpdateCharacterSpacing().

  • On Windows: CalendarDatePicker is a composite control that doesn't have a direct CharacterSpacing property like text controls do. The existing implementation tried to set platformDatePicker.CharacterSpacing = datePicker.CharacterSpacing.ToEm() but CalendarDatePicker doesn't expose this property.

Solution

Modified the Windows-specific UpdateCharacterSpacing method in DatePickerExtensions.cs to:

  1. Traverse the visual tree of the CalendarDatePicker to find internal TextBlock elements
  2. Apply character spacing to each TextBlock using the existing CharacterSpacing.ToEm() conversion
  3. Handle loading state using the OnLoaded pattern to ensure the visual tree is available
public static void UpdateCharacterSpacing(this CalendarDatePicker platformDatePicker, IDatePicker datePicker)
{
    var characterSpacing = datePicker.CharacterSpacing;
    
    if (platformDatePicker.IsLoaded)
    {
        ApplyCharacterSpacingToTextBlocks(platformDatePicker, characterSpacing);
    }
    else
    {
        platformDatePicker.OnLoaded(() => ApplyCharacterSpacingToTextBlocks(platformDatePicker, characterSpacing));
    }
}

static void ApplyCharacterSpacingToTextBlocks(CalendarDatePicker platformDatePicker, double characterSpacing)
{
    var textBlocks = platformDatePicker.GetChildren<Microsoft.UI.Xaml.Controls.TextBlock>();
    var characterSpacingEm = characterSpacing.ToEm();
    
    foreach (var textBlock in textBlocks)
    {
        if (textBlock != null)
        {
            textBlock.CharacterSpacing = characterSpacingEm;
        }
    }
}

Testing

  • Added comprehensive test cases in DatePickerHandlerTests.Windows.cs to verify character spacing is correctly applied
  • Created Issue30066 test case that reproduces the original problem and validates the fix
  • The fix handles both initial character spacing and dynamic updates

Before/After

Before: Setting CharacterSpacing = 10 on a DatePicker had no visual effect on Windows.

After: Character spacing is properly applied to the DatePicker text display on Windows, matching the behavior on other platforms.

Fixes #30066.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

@Copilot Copilot AI changed the title [WIP] [Windows] DatePicker CharacterSpacing Property Not Working on Windows Fix DatePicker CharacterSpacing property not working on Windows platform Jun 23, 2025
@Copilot Copilot AI requested a review from mattleibow June 23, 2025 15:25
Copilot finished work on behalf of mattleibow June 23, 2025 15:25
static void ApplyCharacterSpacingToTextBlocks(CalendarDatePicker platformDatePicker, double characterSpacing)
{
// Find all TextBlock elements within the CalendarDatePicker and apply character spacing
var textBlocks = platformDatePicker.GetChildren<Microsoft.UI.Xaml.Controls.TextBlock>();
Copy link
Contributor

@sheiksyedm sheiksyedm Jun 23, 2025

Choose a reason for hiding this comment

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

@copilot Can you directly access the placeholder TextBlock element in the CalendarDatePicker like below?
platformDatePicker.GetDescendantByName("DateText");

static void ApplyCharacterSpacingToTextBlocks(CalendarDatePicker platformDatePicker, double characterSpacing)
{
// Find all TextBlock elements within the CalendarDatePicker and apply character spacing
var textBlocks = platformDatePicker.GetChildren<Microsoft.UI.Xaml.Controls.TextBlock>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Like in other parts of the framework, can use the extension method

internal static T? GetDescendantByName<T>(this DependencyObject parent, string elementName) where T : DependencyObject


foreach (var textBlock in textBlocks)
{
if (textBlock != null)
Copy link
Contributor

Choose a reason for hiding this comment

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

if (textBlock is not null)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to use if (textBlock is not null) pattern matching in commit ba3447c.

@@ -89,5 +90,36 @@ Color GetNativeTextColor(DatePickerHandler datePickerHandler)

return null;
}

[Fact]
public async Task CharacterSpacingInitializesCorrectly()
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you create another test to validate updates? CharacterSpacingUpdatesCorrectly passing different CharacterSpacing values.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added CharacterSpacingUpdatesCorrectly test that validates character spacing updates with different values (5.0 to 15.0) in commit ba3447c.

if (textBlock != null && textBlock.CharacterSpacing > 0)
{
// Convert back from Em to original value (reverse of ToEm() calculation)
return textBlock.CharacterSpacing / (0.0624 * 1000);
Copy link
Contributor

Choose a reason for hiding this comment

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

Could create an extension method to convert back from Em. In the extension method, include comments explaining the details.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Created FromEm extension method in CharacterSpacingExtensions.cs with comprehensive XML documentation explaining the conversion details. Updated the test to use this method instead of manual calculation in commit ba3447c.

…method, and include CharacterSpacingUpdatesCorrectly test

Co-authored-by: jsuarezruiz <[email protected]>
@Copilot Copilot AI requested a review from jsuarezruiz June 24, 2025 06:25
Copilot finished work on behalf of jsuarezruiz June 24, 2025 06:25
@jsuarezruiz
Copy link
Contributor

/azp run

Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@jsuarezruiz
Copy link
Contributor

The added FromEm method is not part of the publicAPIs, could you add it?

C:\a\_work\1\s\src\Core\src\Platform\Windows\CharacterSpacingExtensions.cs(23,24): error RS0016: Symbol 'FromEm' is not part of the declared public API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) [C:\a\_work\1\s\src\Core\src\Core.csproj::TargetFramework=net9.0-windows10.0.19041.0]
C:\a\_work\1\s\src\Core\src\Platform\Windows\CharacterSpacingExtensions.cs(23,24): error RS0016: Symbol 'FromEm' is not part of the declared public API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) [C:\a\_work\1\s\src\Core\src\Core.csproj::TargetFramework=net9.0-windows10.0.20348.0]
    2 Error(s)

Copy link
Contributor Author

Copilot AI commented Jun 27, 2025

The added FromEm method is not part of the publicAPIs, could you add it?

C:\a\_work\1\s\src\Core\src\Platform\Windows\CharacterSpacingExtensions.cs(23,24): error RS0016: Symbol 'FromEm' is not p...

Added FromEm method to Windows PublicAPI unshipped declarations in commit a921d93.

Copilot finished work on behalf of jsuarezruiz June 27, 2025 06:53
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.

[Windows] DatePicker CharacterSpacing Property Not Working on Windows
4 participants