stringformat - Medición de texto en WPF
xaml decimal format (4)
¡Es muy simple y hecho por la clase FormattedText! Intentalo.
Usando WPF, ¿cuál es la forma más eficiente de medir un gran número de cadenas cortas? Específicamente, me gustaría determinar la altura de visualización de cada cadena, dado el formato uniforme (la misma fuente, tamaño, peso, etc.) y el ancho máximo que puede ocupar la cadena.
La técnica de nivel más bajo (y, por lo tanto, ofrece el mayor margen para optimizaciones creativas) es utilizar GlyphRuns.
No está muy bien documentado, pero escribí un pequeño ejemplo aquí:
http://smellegantcode.wordpress.com/2008/07/03/glyphrun-and-so-forth/
El ejemplo calcula la longitud de la cadena como un paso necesario antes de representarla.
Puede usar la propiedad DesiredSize en un TextBox renderizado para obtener la altura y el ancho
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 tiene un gran número de cadenas, puede ser más rápido pre-calcular primero la altura y el ancho de cada letra y símbolo individual en una fuente dada, y luego hacer un cálculo basado en los caracteres de la cadena. Esto puede no ser 100% preciso debido al kerning, etc.
En WPF:
Recuerde llamar a Measure () en el TextBlock antes de leer la propiedad DesiredSize.
Si el TextBlock se creó sobre la marcha y aún no se muestra, primero debe llamar a Measure (), así:
MyTextBlock.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
return new Size(MyTextBlock.DesiredSize.Width, MyTextBlock.DesiredSize.Height);
En Silverlight:
No hay necesidad de medir.
return new Size(TextBlock.ActualWidth, TextBlock.ActualHeight);
El código completo se ve así:
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
}