顺利解决textblock显示文字不完全的问题:
There could be many scenarios when you'd need to be able to dipslay a text in your WP7 application which doesn't fit on the screen. The easiest way to approach to solve this would be to utilize the ScrollViewer control as a host for a TextBlock. Something like that:
You would think that we're done but as usual the "devil is in the details". If you assign a long text to the TextBlock you will see that part of this text could be truncated and an empty space would be displayed when scrolling to the end: http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-86-10/4188.empty_5F00_scroll.PNG
The reason for this behavior is that any element that must be displayed beyond the area which is larger than 2048x2048 pixels would be clipped by the platform. I was told that this limitation had been dictated by a combination of hardware limitation and performance considerations. To workaround this limitation we'd need to break out the text into a separate blocks and create a TextBlock for each of this text blocks. So to make the life easier for myself and for you I created a custom control which I called ScrollableTextBlock which wraps this logic. So I created a custom control which derives from Control and implements Text property:
public class ScrollableTextBlock : Control
{
private StackPanel stackPanel;
public ScrollableTextBlock()
{
// Get the style from generic.xaml
this.DefaultStyleKey = typeof(ScrollableTextBlock);
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
"Text",
typeof(string),
typeof(ScrollableTextBlock),
new PropertyMetadata("ScrollableTextBlock", OnTextPropertyChanged));
public string Text
{
get
{
return (string)GetValue(TextProperty);
}
set
{
SetValue(TextProperty, value);
}
}
private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ScrollableTextBlock source = (ScrollableTextBlock)d;
string value = (string)e.NewValue;
source.ParseText(value);
}
}
And here's the ParseText method which is also a part of this control:
private void ParseText(string value)
{
if (this.stackPanel == null)
{
return;
}
// Clear previous TextBlocks
this.stackPanel.Children.Clear();
// Calculate max char count
int maxTexCount = this.GetMaxTextSize();
if (value.Length < maxTexCount)
{
TextBlock textBlock = this.GetTextBlock();
textBlock.Text = value;
this.stackPanel.Children.Add(textBlock);
}
else
{
int n = value.Length / maxTexCount;
int start = 0;
// Add textblocks
for (int i = 0; i < n; i++)
{
TextBlock textBlock = this.GetTextBlock();
textBlock.Text = value.Substring(start, maxTexCount);
this.stackPanel.Children.Add(textBlock);
start = maxTexCount;
}
// Pickup the leftover text
if (value.Length % maxTexCount > 0)
{
TextBlock textBlock = this.GetTextBlock();
textBlock.Text = value.Substring(maxTexCount * n, value.Length - maxTexCount * n);
this.stackPanel.Children.Add(textBlock);
}
}
}
In the code above I measure the text length and if it's greater that maxTextCount I break the text into a separate blocks and create a new TextBlock with this text. After the TextBlock is created I add it to the StackPanel. To make a picture complete here's how the control's style looks like: