Microsoft-ui-xaml: Setting TextDecoration = None on TextBlock does not remove the strike through after applying it

Created on 23 Jul 2019  路  4Comments  路  Source: microsoft/microsoft-ui-xaml

Describe the bug
I am trying to strike through a TextBlock when the user taps it. This works great, but it's not possible to clear the strike through decoration once it's been applied.

Steps to reproduce the bug

  1. Add a TextBlock to a page
  2. Add a Tapped event
  3. Add the following code:
        private void TextBlock_Tapped(object sender, TappedRoutedEventArgs e)
        {
            var tb = (TextBlock)sender;
            if(tb.TextDecorations == Windows.UI.Text.TextDecorations.None)
            {
                tb.TextDecorations = Windows.UI.Text.TextDecorations.Strikethrough;
                tb.Foreground = new SolidColorBrush(Colors.Gray);
            }
            else
            {
                tb.TextDecorations = Windows.UI.Text.TextDecorations.None;
                tb.Foreground = new SolidColorBrush(Colors.Black);
            }
        }

Expected behavior
Tapping the TextBlock applies a strike through and changes the colour to gray. That works. Tapping it again should change the colour to black and remove the strike through. The colour changes but the strike through isn't removed.

Version Info
1903

NuGet package version:
N/A

Question
Is there a work around to this, because it's core for the UI I'm working on.

area-TextBlocks bug needs-winui-3 team-Rendering

Most helpful comment

@knightmeister Yes, this totally looks like a bug in the TextBlock control. As a guess, I'd say it's not looking to do anything when the decoration is set to None, when it should also look to remove anything that's already there.

Fortunately, there's a simple workaround:

    private void TextBlock_Tapped(object sender, TappedRoutedEventArgs e)
    {
        var tb = (TextBlock)sender;
        if (tb.TextDecorations == TextDecorations.None)
        {
            tb.TextDecorations = Windows.UI.Text.TextDecorations.Strikethrough;
            tb.Foreground = new SolidColorBrush(Colors.Gray);
        }
        else
        {
+           var text = tb.Text;
+           tb.Text = string.Empty;
            tb.TextDecorations = TextDecorations.None;
+           tb.Text = text;
            tb.Foreground = new SolidColorBrush(Colors.Black);
        }
    }

All 4 comments

@knightmeister Yes, this totally looks like a bug in the TextBlock control. As a guess, I'd say it's not looking to do anything when the decoration is set to None, when it should also look to remove anything that's already there.

Fortunately, there's a simple workaround:

    private void TextBlock_Tapped(object sender, TappedRoutedEventArgs e)
    {
        var tb = (TextBlock)sender;
        if (tb.TextDecorations == TextDecorations.None)
        {
            tb.TextDecorations = Windows.UI.Text.TextDecorations.Strikethrough;
            tb.Foreground = new SolidColorBrush(Colors.Gray);
        }
        else
        {
+           var text = tb.Text;
+           tb.Text = string.Empty;
            tb.TextDecorations = TextDecorations.None;
+           tb.Text = text;
            tb.Foreground = new SolidColorBrush(Colors.Black);
        }
    }

Yes, this is an old bug. The TextDecoration property incorrectly does not mark the element as needing rendering when its value changed.

Thanks for the work around @mrlacey, works well.

I think this is something that can only be fixed with WinUI 3.

Was this page helpful?
0 / 5 - 0 ratings