2009-03-10 13 views
17

El uso de WPF, ¿cuál es la forma más eficiente para medir un gran número de cadenas cortas? Específicamente, me gustaría para determinar la altura de la pantalla de cada cadena, dado el formato uniforme (la misma fuente, el tamaño, el peso, etc.) y la anchura máxima de la cadena puede ocupar?texto de medición en WPF

+1

La misma pregunta en los foros de MSDN tiene algunas soluciones mejores: http://social.msdn.microsoft.com/Forums/en-US/wpf/ Tema/a450b0aa-7086-4145-9eff-a779571b6187/ – srgstm

Respuesta

12

La técnica de nivel más bajo (y por lo tanto, que ofrece el mayor margen para optimizaciones creativas) es utilizar GlyphRuns.

no es muy bien documentada, pero me escribió un pequeño ejemplo aquí:

http://smellegantcode.wordpress.com/2008/07/03/glyphrun-and-so-forth/

El ejemplo se resuelve la longitud de la cadena como un paso necesario antes de mostrarlos.

3

Puede utilizar la propiedad DesiredSize en un cuadro de texto prestados para obtener la altura y la anchura

using System.Windows.Threading; 

... 

Double TextWidth = 0; 
Double TextHeight = 0; 
... 

MyTextBox.Text = "Words to measure size of"; 
this.Dispatcher.BeginInvoke(
    DispatcherPriority.Background, 
    new DispatcherOperationCallback(delegate(Object state) { 
     var size = MyTextBox.DesiredSize; 
     this.TextWidth = size.Width; 
     this.TextHeight = size.Height; 
     return null; 
    } 
) , null); 

Si usted tiene un gran número de cadenas puede ser más rápido a la primera pre-calualte la altura y la anchura de cada indiviudal letra y símbolo en una fuente dada, y luego hacer un cálculo basado en los caracteres de cadena. Esto puede no ser 100% exacto debido a interletraje, etc.

5

es muy simple y hecho por clase FormattedText! Inténtelo.

+0

FormattedText no está disponible en UniversalWindows, ayúdame! –

5

En WPF:

recuerde llamar a Medida() en el TextBlock antes de leer la propiedad DesiredSize.

Si el TextBlock fue creado en la marcha, y sin embargo no se muestra, usted tiene que llamar a Medida() primero, así:

MyTextBlock.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 

return new Size(MyTextBlock.DesiredSize.Width, MyTextBlock.DesiredSize.Height); 

En Silverlight:

No es necesario medir

return new Size(TextBlock.ActualWidth, TextBlock.ActualHeight); 

El código completo es el siguiente:

public Size MeasureString(string s) { 

    if (string.IsNullOrEmpty(s)) { 
     return new Size(0, 0); 
    } 

    var TextBlock = new TextBlock() { 
     Text = s 
    }; 

#if SILVERLIGHT 
    return new Size(TextBlock.ActualWidth, TextBlock.ActualHeight); 
#else 
    TextBlock.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 

    return new Size(TextBlock.DesiredSize.Width, TextBlock.DesiredSize.Height); 
#endif 
}