wp7超大文本显示控件 垂直滚动
2012-03-06 09:27
281 查看
wp7中textblock显示有文本数量限制。貌似超过2048个字符就不显示了。
从国外网站找了一个控件,实现加载大量文本显示,并且垂直滚动浏览。
实现原理其实挺简单的,就是动态创建多个textblock控件,每个控件显示部分内容。
有点,加载大量文本时,垂直方向滚动浏览,用户体验度较高(个人感觉比一页页翻页舒服多了)
缺点,由于加载了多个控件,所以加载速度慢(与文本长度有关),这也许时微软限制显示数量的原因。
上代码:
个人感觉,分页算法还是有改进空间的,尽可能减少控件数目,并且以后可以考虑实现动态加载,应该可以解决加载速度问题。
这里抛砖引玉了。
从国外网站找了一个控件,实现加载大量文本显示,并且垂直滚动浏览。
实现原理其实挺简单的,就是动态创建多个textblock控件,每个控件显示部分内容。
有点,加载大量文本时,垂直方向滚动浏览,用户体验度较高(个人感觉比一页页翻页舒服多了)
缺点,由于加载了多个控件,所以加载速度慢(与文本长度有关),这也许时微软限制显示数量的原因。
上代码:
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.IO; using System.Text; namespace wwb.Phone.Ctrls { public class ScrollableTextBlock : Control { private StackPanel stackPanel; private TextBlock measureBlock; 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); } public override void OnApplyTemplate() { base.OnApplyTemplate(); this.stackPanel = this.GetTemplateChild("StackPanel") as StackPanel; this.ParseText(this.Text); } private void ParseTextHide(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); } } } private void ParseText(string value) { StringReader reader = new StringReader(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 { string line = ""; while (reader.Peek() > 0) { line = reader.ReadLine(); ParseLine(line); } } } private void ParseLine(string line) { int lineCount = 0; int maxLineCount = GetMaxLineCount(); string tempLine = line; StringBuilder sbLine = new StringBuilder(); while (lineCount < maxLineCount) { int charactersFitted = MeasureString(tempLine, (int)this.Width); string leftSide = tempLine.Substring(0, charactersFitted); sbLine.Append(leftSide); tempLine = tempLine.Substring(charactersFitted, tempLine.Length - (charactersFitted)); lineCount++; } TextBlock textBlock = this.GetTextBlock(); textBlock.Text = sbLine.ToString(); this.stackPanel.Children.Add(textBlock); if (tempLine.Length > 0) { ParseLine(tempLine); } } private int MeasureString(string text, int desWidth) { int nWidth = 0; int charactersFitted = 0; StringBuilder sb = new StringBuilder(); //get original size Size size = MeasureString(text); if (size.Width > desWidth) { string[] words = text.Split(' '); sb.Append(words[0]); for (int i = 1; i < words.Length; i++) { sb.Append(" " + words[i]); nWidth = (int)MeasureString(sb.ToString()).Width; if (nWidth > desWidth) { sb.Remove(sb.Length - words[i].Length, words[i].Length); break; } } charactersFitted = sb.Length; } else { charactersFitted = text.Length; } return charactersFitted; } private Size MeasureString(string text) { if (this.measureBlock == null) { this.measureBlock = this.GetTextBlock(); } this.measureBlock.Text = text; return new Size(measureBlock.ActualWidth, measureBlock.ActualHeight); } private int GetMaxTextSize() { // Get average char size Size size = this.MeasureText(" "); // Get number of char that fit in the line int charLineCount = (int)(this.Width / size.Width); // Get line count int lineCount = (int)(2048 / size.Height); return charLineCount * lineCount / 2; } private int GetMaxLineCount() { Size size = this.MeasureText(" "); // Get number of char that fit in the line int charLineCount = (int)(this.Width / size.Width); // Get line count int lineCount = (int)(2048 / size.Height) - 5; return lineCount; } private TextBlock GetTextBlock() { TextBlock textBlock = new TextBlock(); textBlock.TextWrapping = TextWrapping.Wrap; textBlock.FontSize = this.FontSize; textBlock.FontFamily = this.FontFamily; // textBlock.FontStyle = this.FontStyle; textBlock.FontWeight = this.FontWeight; textBlock.Foreground = this.Foreground; textBlock.Margin = new Thickness(0, 0, MeasureText(" ").Width, 0); return textBlock; } private Size MeasureText(string value) { TextBlock textBlock = this.GetTextBlockOnly(); textBlock.Text = value; return new Size(textBlock.ActualWidth, textBlock.ActualHeight); } private TextBlock GetTextBlockOnly() { TextBlock textBlock = new TextBlock(); textBlock.TextWrapping = TextWrapping.Wrap; textBlock.FontSize = this.FontSize; textBlock.FontFamily = this.FontFamily; textBlock.FontWeight = this.FontWeight; return textBlock; } } }
个人感觉,分页算法还是有改进空间的,尽可能减少控件数目,并且以后可以考虑实现动态加载,应该可以解决加载速度问题。
这里抛砖引玉了。
相关文章推荐
- MFC EDIT控件自动显示垂直滚动条
- 多行多列,无限滚动文本显示控件
- MFC EDIT控件自动显示垂直滚动条
- iOS - 支持水平 / 垂直显示自动滚动的跑马灯控件 --- SKAutoScrollLabel 的使用和实现
- 自定义文字滚动控件,用于单行文本的显示,当文字过长的时候,就会自动的向左滚动
- 【Android自学笔记】android实现TextView垂直滚动显示
- Android自定义垂直滚动自动选择日期控件
- CTextUI 文本控件 显示数字方法
- IE6,7默认显示垂直滚动条
- Edit控件单行显示文字垂直居中的办法
- 编辑框控件:MFC编辑框自动换行,垂直滚动条自动下移
- [置顶] 关于图片与文字在一行显示时,文本的垂直方向位置的设置
- 在状态栏中显示滚动文本
- 水晶报表文本垂直居中显示
- Labview学习笔记——如何用按钮来控制某控件(例如文本控件)的显示与隐藏
- Android开发中TextView文本过长滚动显示实现方法分析
- Winform 控制另一窗体控件文本显示
- android EditText控件显示为文本框而不是文本线
- .net2005 radiosbuttonlist 控件控制文本显示!
- 自定义UI-TextView实现文本自动滚动显示