There is a limitation on a size of a control in Windows Phone 7 of 2048 pixels, and I needed to sometimes display a long list of items. Here is how I did that. First off, the XAML portion:
<ScrollViewer Tap="ScrollViewer_Tap" Name="AnswerScrollViewer" Grid.Row="1" Height="Auto"> <StackPanel x:Name="AnswerScrollViewerStackPanel"> <TextBlock x:Name="Answer" Width="430" Text="" Tag="" FontSize="28" TextWrapping="Wrap" /> </StackPanel> </ScrollViewer>
There is a ScrollViewer that I use to scroll a long list. It has a StackPanel (because ScrollViewer can only have one control inside it, and I will use several controls to display a long list of text). Then the StackPanel has the "Answer" TextBlock control that is used when there is no need to display the long list.
And now, on to the magic. This is a part of the function that assigns the text to the text block.
//more on the MeasureSizeOfATextBlock() later double futureAnswerTextBlockSize = MeasureSizeOfATextBlock(Answer, Answer.Tag.ToString()); //MAXCONTROLHEIGHT is a constant, close to 2048 if (futureAnswerTextBlockSize > MAXCONTROLHEIGHT) { //I split my string by the carriage returns string[] options = { "\r\n" }; string[] arr = Answer.Tag.ToString().Split(options, StringSplitOptions.None); //Let's create the first text block to start displaying the list TextBlock b = new TextBlock(); b.Foreground = DarkThemeIsVisible() //more on this function later ? new SolidColorBrush(Color.FromArgb(255, 255, 255, 255)) : new SolidColorBrush(Color.FromArgb(255, 0, 0, 0)); b.VerticalAlignment = System.Windows.VerticalAlignment.Top; b.FontSize = ANSWERTEXTFONTSIZE; b.TextWrapping = TextWrapping.Wrap; b.Width = 430; b.Name = "sb1"; //the name really does not matter int j = 0; //This constant will help me omit the new line before the first line of text bool omitCRForNewLine = true; //and let's display the text while (j < arr.Length) { if (!omitCRForNewLine) b.Text += Environment.NewLine + arr[j]; else b.Text += arr[j]; omitCRForNewLine = false; j += 1; if (b.ActualHeight > MAXCONTROLHEIGHT - 20) { //The height of the control is getting closer to the limit //so let's add this control to the stack panel, and ... AnswerScrollViewerStackPanel.Children.Add(b); //create a new control to continue displaying the text b = new TextBlock(); b.Foreground = DarkThemeIsVisible() ? new SolidColorBrush(Color.FromArgb(255, 255, 255, 255)) : new SolidColorBrush(Color.FromArgb(255, 0, 0, 0)); b.VerticalAlignment = System.Windows.VerticalAlignment.Top; b.FontSize = ANSWERTEXTFONTSIZE; b.TextWrapping = TextWrapping.Wrap; b.Width = 430; b.Name = "sb" + j.ToString(); //reset this variable to avoid the empty line in the beginning omitCRForNewLine = true; } if (j == arr.Length - 1) //add the last text block AnswerScrollViewerStackPanel.Children.Add(b); } //hide Answer text block, I am not using it Answer.Visibility = System.Windows.Visibility.Collapsed; } else { //if one text block is enough, everything is simple Answer.Visibility = System.Windows.Visibility.Visible; Answer.Text = Answer.Tag.ToString(); Answer.Foreground = DarkThemeIsVisible() ? new SolidColorBrush(Color.FromArgb(255, 255, 255, 255)) : new SolidColorBrush(Color.FromArgb(255, 0, 0, 0)); Answer.VerticalAlignment = System.Windows.VerticalAlignment.Top; Answer.FontSize = ANSWERTEXTFONTSIZE; }
And here are the two helper functions. The first function takes a control as input, and a line of text. Then it creates a TextBlock, assigns some parameters and returns the ActualHeight parameter of the control.
private double MeasureSizeOfATextBlock(TextBlock t, string text) { TextBlock a = new TextBlock(); a.Width = t.Width; a.FontFamily = t.FontFamily; a.FontStyle = t.FontStyle; a.FontWeight = t.FontWeight; a.FontSize = t.FontSize; a.Text = text; a.TextWrapping = t.TextWrapping; return a.ActualHeight; }
This function determines whether the user has the dark or light theme selected.
private bool DarkThemeIsVisible() { Visibility v = (Visibility)Resources["PhoneDarkThemeVisibility"]; if (v == System.Windows.Visibility.Visible) return true; return false; }
No comments:
Post a Comment