Silverlight 以编程方式确定文本框中的最大匹配(WP7)

Silverlight 以编程方式确定文本框中的最大匹配(WP7),silverlight,windows-phone-7,textblock,measure,Silverlight,Windows Phone 7,Textblock,Measure,我目前正在为WindowsPhoneSeven编写一个电子书阅读器,我正在尝试将其设计成Kindle阅读器。为了做到这一点,我需要把我的书分成几页,当添加可变字体大小时,这将变得更加复杂 为了做到这一点,我只需在文本块中添加一个单词,直到它高于其容器。但是,正如您可以想象的那样,对于一个超过120000字的文档,这需要一段不可接受的时间 有没有一种方法可以让我知道文本何时会超出边界(逻辑上将其划分为多个页面),而无需实际渲染?这样,我就可以在后台线程中运行它,以便用户可以同时继续阅读 到目前为止

我目前正在为WindowsPhoneSeven编写一个电子书阅读器,我正在尝试将其设计成Kindle阅读器。为了做到这一点,我需要把我的书分成几页,当添加可变字体大小时,这将变得更加复杂

为了做到这一点,我只需在文本块中添加一个单词,直到它高于其容器。但是,正如您可以想象的那样,对于一个超过120000字的文档,这需要一段不可接受的时间

有没有一种方法可以让我知道文本何时会超出边界(逻辑上将其划分为多个页面),而无需实际渲染?这样,我就可以在后台线程中运行它,以便用户可以同时继续阅读

到目前为止,我唯一想到的是找出textblock是如何决定其边界的(在度量调用中?),但我不知道如何找到该代码,因为reflector没有显示任何内容


提前谢谢

您可以查询textBlock内部AIK使用的FormattedText类。由于这是用于格式化文本以准备呈现的类,因此这是可用的最低级类,应该很快。

从我所看到的来看,Kindle应用程序似乎使用了与您建议的算法类似的算法。请注意:

  • 它通常显示整本书的%位置-它不显示总页数

  • 如果你改变字体大小,那么页面上的第一个单词保持不变(这就是%的来源)——因此Kindle应用程序只需在页面上的第一个单词保持不变的情况下进行一页大小的重新分页

  • 如果您更改字体大小,然后滚动回第一页,那么实际上存在一个中断-他们再次向前拉内容以填充第一页

基于此,我建议您不要为整本书编制索引。相反,只需根据某种“位置”(例如,字符数-以百分比显示)将注意力集中在当前页面上。如果你必须在后台线程上做一些事情,那么只需看看下一页(也许还有上一页),这样滚动就能更具响应性

为了进一步优化您的体验,您可以尝试对当前算法进行以下几项更改:

  • 尝试不同的起点,搜索算法的增量-无需从一个单词开始,然后一次只添加一个单词

  • 假设您的大多数书籍都是ASCII码,请尝试缓存常用字符的宽度,然后自己计算文本块的宽度


除此之外,我还想尝试在TextBlock中使用
块-可能可以获得TextBlock中每次运行的相对位置-尽管我还没有做到这一点。

我做了一些类似的事情来调整各个文本框的字体大小(以确保它们都适合)。基本上,我在代码中创建一个TextBlock,设置所有属性并检查ActualWidth和ActualHeight属性。下面是一些帮助解决问题的伪代码:

public static String PageText(TextBlock txtPage, String BookText)
{
    TextBlock t = new TextBlock();
    t.FontFamily = txtPage.FontFamily;
    t.FontStyle = txtPage.FontStyle;
    t.FontWeight = txtPage.FontWeight;
    t.FontSize = txtPage.FontSize;
    t.Text = BookText;

    Size Actual = new Size();
    Actual.Width = t.ActualWidth;
    Actual.Height = t.ActualHeight;

    if(Actual.Height <= txtPage.ActualHeight)
        return BookText;

    Double hRatio = txtPage.ActualHeight / Actual.Height;
    return s.Substring((int)((s.Length - 1) * hRatio));
}
公共静态字符串页面文本(TextBlock txtPage,String BookText)
{
TextBlock t=新的TextBlock();
t、 FontFamily=txtPage.FontFamily;
t、 FontStyle=txtPage.FontStyle;
t、 FontWeight=txtPage.FontWeight;
t、 FontSize=txtPage.FontSize;
t、 文本=书本文本;
实际尺寸=新尺寸();
实际宽度=t实际宽度;
实际高度=t实际高度;

如果(Actual.Height我没有找到任何来自微软的关于这个例子的参考资料,叫做“分页原则”

它有一些在Windows Phone中运行的有趣的示例代码

您还可以查看这篇文章和其他关于的文章


代码是可下载的:

不幸的是,这只是一个WPF结构。嗯。我想这可能就是为什么你不能快速滚动几页的原因。我会想一想,但我仍然感到惊讶的是,似乎没有一种方法可以合理地进行手动“测量”。+1,你描述的方式,Kindle设备也可以工作。还有sugg你所做的评估是我唯一能做的(也写wp7阅读器:)-在code TextBlock中使用一页又一页的分页。记为答案,因为这是我这里问题的最佳答案。但可能不是我采取的路线。