AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
25.62k stars 2.22k forks source link

TextAlignment.Right doesn't work with SharedSizeGroup #13777

Open stogle opened 11 months ago

stogle commented 11 months ago

Describe the bug

TextBlocks with TextAlignment.Right that are in Grid columns with SharedSizeGroup defined are not right-aligned.

To Reproduce

Create a new Avalonia C# project targeting Desktop, using Community Toolkit, with Compiled Bindings, then make the following modifications:

MainView.axaml:

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:viewModels="clr-namespace:TextAlignmentBug.ViewModels"
             mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="100"
             x:Class="TextAlignmentBug.Views.MainView"
             x:DataType="viewModels:MainViewModel"
             Design.DataContext="vm:MainViewModel">
    <StackPanel Grid.IsSharedSizeScope="True">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="Column1"
                                  Width="Auto" />
                <ColumnDefinition Width="5" />
                <ColumnDefinition SharedSizeGroup="Column2"
                                  Width="Auto" />
            </Grid.ColumnDefinitions>

            <TextBlock Text="Right"
                       TextAlignment="Right"
                       Grid.Column="0" />

            <TextBlock Text="Left"
                       TextAlignment="Left"
                       Grid.Column="2" />
        </Grid>

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="Column1"
                                  Width="Auto" />
                <ColumnDefinition Width="5" />
                <ColumnDefinition SharedSizeGroup="Column2"
                                  Width="Auto" />
            </Grid.ColumnDefinitions>

            <TextBlock Text="LongerRight"
                       TextAlignment="Right"
                       Grid.Column="0" />

            <TextBlock Text="LongerLeft"
                       TextAlignment="Left"
                       Grid.Column="2" />
        </Grid>
    </StackPanel>
</UserControl>
  1. Observe that the design view appears correct ("Right" and "LongerRight" appear right-aligned, while "Left" and "LongerLeft" appear left-aligned)
  2. Run the application in Debug configuration
  3. Observe that the running application appears incorrect ("Right" appears left-aligned, not right-aligned)
  4. Press F12 to open Avalonia DevTools
  5. Select Visual Tree
  6. Ctrl+Shift+click on the "Right" TextBlock
  7. Observe that the TextAlignment property is set to "Right" as expected
  8. Change the TextAlignment property to another value then change it back to "Right"
  9. Observe that the running application now appears correct ("Right" is right-aligned)

Expected behavior

TextBlocks with TextAlignment.Right should always be right-aligned.

Screenshots

Step 1 - Design view (as expected): image

Step 3 - Running application (not as expected): image

Step 7 - DevTools (as expected): image

Step 9 - After toggling TextAlignment in DevTools (now as expected): image

Environment

Additional context

The issue does not occur if SharedSizeGroup is not used but without it one cannot align the contents of two Grids.

timunie commented 11 months ago

@stogle can you test with latest nightly the same sample? We had some text fixes in, but I don't know if that particular area was touched. So would be nice if you can confirm.

stogle commented 10 months ago

@timunie I added https://nuget-feed-nightly.avaloniaui.net/v3/index.json to package sources, changed my "AvaloniaVersion" property to 11.1.999-cibuild0042556-beta, deleted "bin" and "obj" folders and rebuilt. Unfortunately, I see the same results.

timunie commented 10 months ago

Thx for checking

stogle commented 10 months ago

Based on my observation that using DevTools to change the TextAlignment, then change it back again fixes the issue, I've added the following workaround to MainView.axaml.cs:

    protected override void OnLoaded(RoutedEventArgs e)
    {
        // Workaround for https://github.com/AvaloniaUI/Avalonia/issues/13777
        foreach (var textBlock in this.GetVisualDescendants().OfType<TextBlock>())
        {
            TextAlignment textAlignment = textBlock.TextAlignment;
            textBlock.TextAlignment = (TextAlignment)(-1);
            textBlock.TextAlignment = textAlignment;
        }
    }

@timunie Do you have any suggestions for a less "hacky" workaround?

timunie commented 10 months ago

@stogle yeah best would be to try debugging Avalonia and send a PR if you were successful. Also maybe textBlock.InvalidateArrange() can be called instead of manipulating the alignment...

stogle commented 10 months ago

@timunie thanks for the suggestion. InvalidateArrange() didn't work but InvaidateMeasure() did!

Debugging Avalonia will have to wait until I can allocate some time for that. It seems like grid length changes due to shared size scope aren't invalidating everything that should be invalidated.

busitech commented 2 weeks ago

The SharedSizeGroup was properly changing the Bounds of the TextBlock, making it wider, but this did not cause the TextLayout to invalidate, leaving columns with TextAlignment.Right appear left justified until something forced the redraw. We have attached a PR.