silverlight windows-phone-7 textblock measure

silverlight - Determinación programática del ajuste máximo en el cuadro de texto(WP7)



windows-phone-7 textblock (4)

Actualmente estoy escribiendo un lector de libros electrónicos para Windows Phone Seven, y estoy tratando de diseñarlo como el lector de Kindle. Para hacerlo, necesito dividir mis libros en páginas, y esto se volverá mucho más complejo cuando se agreguen tamaños de fuente variables.

Para hacer esto en este momento, solo agrego una palabra a la vez en el bloque de texto hasta que sea más alto que su contenedor. Sin embargo, como se puede imaginar, con un documento de más de 120,000 palabras, esto lleva un período inaceptable.

¿Hay alguna manera de saber cuándo el texto excedería los límites (dividiéndolo lógicamente en páginas) sin tener que representarlo realmente? De esa forma, podría ejecutarlo en un hilo de fondo para que el usuario pueda seguir leyendo mientras tanto.

Hasta ahora, la única idea que se me ha ocurrido es averiguar cómo el bloque de texto decide sus límites (¿en la llamada de medida?), Pero no tengo idea de cómo encontrar ese código, porque el reflector no mostró nada.

¡Gracias por adelantado!


Por lo que puedo ver, la aplicación Kindle parece usar un algoritmo similar al que sugieres. Tenga en cuenta que:

  • generalmente muestra el% de posición a través del libro, no muestra el número total de páginas.

  • si cambia el tamaño de la fuente, la primera palabra de la página sigue siendo la misma (de ahí que provenga el%), por lo que la aplicación Kindle solo paga una página por la repaginación, suponiendo que la primera palabra de la página permanezca igual.

  • si cambia el tamaño de la fuente y luego vuelve a la primera página, en realidad hay una discontinuidad: retiran el contenido nuevamente para llenar la primera página.

En base a esto, le sugiero que no indexe todo el libro. En su lugar, simplemente concéntrese en la página actual en función de una "posición" de algún tipo (por ejemplo, el recuento de caracteres, que se muestra en forma de porcentaje). Si tiene que hacer algo en un hilo de fondo, simplemente mire la página siguiente (y tal vez la página anterior) para que el desplazamiento sea más receptivo.

Además de optimizar su experiencia, hay un par de cambios que podría hacer a su algoritmo actual que podría intentar:

  • pruebe con un punto de partida diferente y un incremento de búsqueda para su algoritmo; no es necesario comenzar con una palabra y luego solo agregar una palabra a la vez.

  • suponiendo que la mayoría de sus libros son ASCII, intente guardar en caché el ancho de los caracteres comunes y luego resuelva el ancho de los bloques de texto usted mismo.

Más allá de eso, también me gustaría intentar usar bloques <Run> en tu TextBlock, es posible obtener la posición relativa de cada ejecución dentro de TextBlock, aunque todavía no he logrado hacerlo.


Puede consultar la clase FormattedText que se utiliza AFAIK dentro de textBlock. ya que esta es la clase que se utiliza para formatear texto en preparación para la representación, esta es la clase de menor nivel disponible, y debe ser rápida.


Hago algo similar para ajustar el tamaño de fuente para cuadros de texto individuales (para asegurar que todos encajen). Básicamente, creo un código de texto en el código, establezco todas mis propiedades y verifico las propiedades ActualWidth y ActualHeight. Aquí hay un pseudo código para ayudarlo con su problema:

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)); }

Lo anterior es código no probado, pero con suerte puede comenzar. Básicamente, ve si el texto puede caber en la caja, si es así, está listo. Si no, averigua qué porcentaje del texto puede caber y lo devuelve. Esto no tiene en cuenta los saltos de palabra, y puede no ser una combinación perfecta, pero debe acercarlo.

Puede modificar este código para devolver la longitud en lugar de la subcadena real y usarla como el tamaño de su página. Crear el bloque de texto en el código (sin visualización) en realidad funciona bastante bien (lo hago en algunas vistas de tabla sin retraso notable). No enviaría las 120,000 palabras a esta función, sino un subconjunto razonable de algún tipo.

Una vez que tenga la longitud ideal, puede usar un RegEx para dividir el libro en páginas. Hay ejemplos en este sitio de RegEx que se rompen en los límites de palabras después de una longitud específica.

Otra opción es calcular el tamaño de página con anticipación para cada tamaño de fuente potencial (y codificarlo con una instrucción de conmutación). Esto podría volverse loco si permite combinaciones de fuentes y tamaños, y sería horrible si permitiera fuentes / tamaños mixtos, pero funcionaría muy bien. Lo más probable es que tenga un rango particular de tamaños legibles, y solo unas pocas fuentes. Crear una aplicación de prueba para calcular la longitud del texto de una página para cada una de estas combinaciones no sería tan difícil y probablemente haría su vida más fácil, incluso si no se "siente" bien como programador :)


No encontré ninguna referencia a este ejemplo de Microsoft llamado: "Principios de la paginación".

Tiene un código de ejemplo interesante que se ejecuta en Windows Phone.

http://msdn.microsoft.com/en-us/magazine/hh205757.aspx

También puede consultar este artículo sobre Transiciones de página en Windows Phone y este otro acerca de los toques finales en el proyecto de E-Book .

El código se puede descargar: http://archive.msdn.microsoft.com/mag201111UIFrontiers/Release/ProjectReleases.aspx?ReleaseId=5776