views:

78

answers:

2

I am attempting to use the WrapPanel and two TextBlocks to append an asterisk (*) to the left side of some text, allow the text to wrap, and force the text to be right aligned. I have successfully done so by creating a WrapPanel with the FlowDirection set to RightToLeft and adding my text, followed by the asterisk. However, if the text I use happens to have any non-alphanumeric characters at the end of the line it is inexplicably forced to the front of the line. I find this behavior to be very strange. I think it must be a bug in WPF and not intended behavior.

Example with Text = Normal Text (Other Text) :

Expected:
* Normal Text (Other
               Text)
Actual:
* Normal Text (Other
               (Text

Feel free to use the following sample code to recreate the issue for yourself. Simply put this in a window with Height and Width = 100, then type "Normal Text (Other Text)" in the TextBox. Or, set the Height and Width to anything you like and write enough text that it is forced to wrap the text, then add punctuation to the end.

Sample Code:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <TextBox Name="input" />
    <WrapPanel Grid.Row="2" FlowDirection="RightToLeft">
        <TextBlock Text="{Binding ElementName=input, Path=Text}" TextWrapping="Wrap"/>
        <TextBlock Text="*" Margin="0,0,3,0"/>
    </WrapPanel>
</Grid>

So, my question(s).

  • Is this a bug, or is this intended?
  • If this is a bug, should I submit it to Microsoft in some way? How?

Since starting this post, I have decided to put the two TextBlocks in a two column grid instead. With the non-asterisk containing TextBlock configured to use a Right TextAlignment I meet all my requirements anyway. Still, I found this to be an interesting issue.

+2  A: 

Try this instead:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <TextBox Name="input" />
    <WrapPanel Grid.Row="2" HorizontalAlignment="Right" >
        <TextBlock Text="*" Margin="0,0,3,0"/>
        <TextBlock Text="{Binding ElementName=input, Path=Text}" TextWrapping="Wrap"/>

    </WrapPanel>
</Grid>

FlowDirection is for use to support languages that are read that from right to left. Since I don't know the rules for languages like that I'm not going to pretend to understand why you are seeing what you are, or if it is a bug. That said I know that changing the FlowDirection isn't the correct way to handle right aligning left to right languages and you should use HorizontalAlignment instead.

(For future reference you submit bugs to Microsoft through the Connect site)

Martin Harris
Works great! As is often the case with convoluted logic like my RightToLeft FlowDirection, there is a much simpler way to do it. I like it better than the grid I described.Is it worth my time to report the odd behavior to Microsoft?
Drew
@Drew Looks like it's expected behaviour. As I say, I don't actually know anything about this, but a little Googling found this link: http://www.i18nguy.com/markup/right-to-left.html
Martin Harris
I can't say that I really understand the rules for changing a language from left-to-right to right-to-left, but I'm sold that this was intended behavior. Well done.
Drew
+1  A: 

In .Net 4 (WPF4) runs are bindable, so you can try something like so:

<TextBlock TextAlignment="Right" TextWrapping="Wrap">
    <Run Text="*" /><Run Text="{Binding ElementName=Input, Path=Text}" />
</TextBlock>

The two Run elements are on the same line because any type of whitespace between the tag boundaries will cause a space to appear between the two runs. (As HTML does.)

YotaXP