Controls and max height

Posted on Октябрь 9, 2011

1


Hello,

I am a Windows Phone 7 developer. I want to share some of my experience to other developers and i am going to start with the thing that is totally not obvious. I have a windows phone 7 myself. I use it very extensively and what i do all of the time — reading. Reading anything from screen. There are a lot of great applications in the Marketplace to read news, RSS, books, etc. Some of them work perfectly, other — have some issues. But the thing I’ve noticed in a big amount of apps — is text not always fits the screen!

Going a bit backward: i know about this bug of Silverlight controls for a long time, but i thought that all developers are aware of it too.

Recently our team was writing an application for big media company. What we got — is application that was written by other people and we needed to fix bugs. People wrote some good code, but made a mistake: they just bind text of the article that is arriving from server to the textblock control.

So you can see text in some textblock.

Than you scroll a bit, you will see this:

As you can see, some text is missing, but the scroll bar is visible and furthermore! You can scroll down!

I have noticed this mistake in some News Applications. To resolve this issue we created a converter. So to start we should place a ContentContainer on the page instead of TextBlock in order to display content we like:

<ContentPresenter Content="{Binding BodyText}" />

And property in the codebehind:

        public string BodyText
        {
            get
            {
                return "Lorem ipsum dolor sit amet, ...";
            }
        }

Than we add the converter:

<ContentPresenter Content="{Binding BodyText,Converter={StaticResource LongTextConverter}}" />

And as the result:


So, as you see, the text is shown fully, and we are coming back to Converter. This solution it not superb but it is working well for usual text. The main idea is to split text on blocks of some length. We chose 2500 chars. And to push each block in Stack Panel. I checked performance on several devices ant it is pretty fast even with huge amount of text. Let’s walk on the code a bit.

We place empty StackPanel and splitting text on blocks with length less than 2500 chars. The best is to split by ‘\n’ in block, so the last NewLine will be the last symbol in the block. The solution is not perfect, and it is not cool, but it is:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			UIElement result = null;

			if (value != null)
			{
				string data = value.ToString();

				if (data.Length <= MinLength)
				{
					result = new TextBlock
								 {
									 Text = data,
									 Style = App.Current.Resources["ArticleBodyStyle"] as Style,
									 HorizontalAlignment = HorizontalAlignment.Stretch
								 };
				}
				else
				{
					StackPanel resultPanel = new StackPanel();
					int min = 0;
					int max = MinLength;
					while (true)
					{
						string temp = data.Substring(min, max - min);
						if (max != data.Length)
						{
							int index = temp.LastIndexOf('\n');
							index = index == -1 ? temp.LastIndexOf('.') + 1 : -1;
							max = (index == -1) ? max : index;
							temp = data.Substring(min, max) + '\n';
							resultPanel.Children.Add(new TextBlock
														 {
															 Margin = new Thickness(12, 0, 12, -30),
															 Text = temp,
															 Style = App.Current.Resources["ArticleBodyStyle"] as Style,
															 HorizontalAlignment = HorizontalAlignment.Stretch
														 });
						}
						else
						{
							resultPanel.Children.Add(new TextBlock
														 {
															 Margin = new Thickness(12, 0, 12, 0),
															 Text = temp,
															 Style = App.Current.Resources["ArticleBodyStyle"] as Style,
															 HorizontalAlignment = HorizontalAlignment.Stretch
														 });
							break;
						}

						min += max;
						max = min + MinLength;
						if (max > data.Length)
						{
							max = data.Length;
						}
					}

					result = resultPanel;
				}
			}

			return result;
		}

Hope this helps!

Реклама