views:

1716

answers:

4

Does anyone have any suggestions on how to justify read-only text (rendered into a TextBlock) in Silverlight 2? WPF supports text justification by way of the TextAlignment enumeration:

public enum TextAlignment
{
    Left,
    Right,
    Center,
    Justify // <--- Missing from Silverlight :(
}

However, Silverlight 2 only supports the following:

public enum TextAlignment
{
    Center,
    Left,
    Right
}

Any ideas or suggestions gratefully received.

A: 

If these dont meet your needs, you should write an extender or converter and bind to that instead of using one of the enums.

Muad'Dib
Not sure which enumeration you're referring to, but the values posted in the question are correct .. according to Reflector and looking at the property values in Blend and VS.NET. Could you elaborate please? On the matter of the Extender and Converter ideas, I don't see how a converter will help :S
PaulJ
The TextAlignment enums.
Muad'Dib
+1  A: 

Off the top of my head, I can think of two not-so-easy ways to do this. One is rather lame; adding spaces between the words. The other would be to somehow parse the text so that each word is it's own text block, you could then use a Grid to left justify the first word of a line and right justify the last word of a line, then space the other blocks in the center cell using a stack panel or similar.

Determining which words are the start and end of a line would involve measuring the rendered size of each block and deciding if it will fit. It's not simple but it should work.

Jeff Yates
Thanks for your answers .. your first approach occurred to me too, however the second one is novel idea and you've given me the idea of potentially using a custom layout panel
PaulJ
A: 

I found a blog post about that - http://math-geek-rock-chick.blogspot.com/2008/08/silverlight-and-text-alignjustify.html. The idea is to divide the text into individual lines and then apply a ScaleTransform to each line scaling the text from left (RenderTransformOrigin=0,0) to right (Scale.X = 1.02). But the method is only good for small pieces of text and will probably brake down if your TextBox size is changing.

texmex5
Thanks, I saw that post before asking the question; it felt really fragile as an approach; but thanks for looking :)
PaulJ
Well lets hope align: justify in March when Silverlight 3 comes out. Right now scale transform seems like the "easyest" way.
texmex5
A: 

Obviously the only solution is splitting text line to words and layout words across the column (as Jeff Yates suggests above). First thing is verifying the idea using Grid container:

<Grid Name="grid1">
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Left" Text="This" Grid.Column="0" />
<TextBlock HorizontalAlignment="Center" Text="is" Grid.Column="2" />
<TextBlock HorizontalAlignment="Center" Text="someprettylongpiece" Grid.Column="4" />
<TextBlock HorizontalAlignment="Right" Text="text" Grid.Column="6" />
</Grid>

Next step is creating custom panel that performs text blocks layout without dealing with Grid:

<JustifiedPanel>
    <TextBlock Text="This"/>
    <TextBlock Text="is"/>
    <TextBlock Text="a"/>
    <TextBlock Text="justified"/>
    <TextBlock Text="line"/>
    <TextBlock Text="of"/>
    <TextBlock Text="text"/>
    <TextBlock Text="that"/>
    <TextBlock Text="demonstrates"/>
    <TextBlock Text="feasibility"/>
</JustifiedPanel>

(Sample source code is available on my blog) Finally I'm going to create JustifiedTextBlock control which will split text onto words and layout them. Nontrivial things here are proper RTL support and correct line splitting.

olegz