2010-06-07 2 views
12

Ho un DataTemplate WPF con due controlli TextBlock (impilati) e quindi alcuni altri elementi al di sotto. A causa di un complicato codice di layout, ho bisogno di conoscere l'altezza dei due elementi TextBlock in modo da poter disegnare alcune linee di connettori fantasiose e allineare altri controlli, ecc.Come si misura la dimensione di un TextBlock in WPF prima del rendering?

Se conosco il testo che sta andando in TextBlocks e conosco il font, ecc., c'è un modo in cui posso calcolare o misurare l'altezza di questi TextBlock senza renderli effettivamente?

risposta

22

Penso che dovrebbe essere sufficiente chiamare il metodo UIElement.Measure(Size) e successivamente controllare la proprietà UIElement.DesiredSize. Per ulteriori informazioni, controllare i collegamenti MSDN forniti.

+0

+1, ma si noti che, oltre al consueto aspetto e la dimensione del font, c'è anche un (ereditato) Proprietà divisoria che [colpisce carattere hinting] (http://blogs.msdn.com/b/text /archive/2009/08/24/wpf-4-0-text-stack-improvements.aspx) (se allineare o meno pixel interi), e questo influenza la larghezza del testo. La proprietà allegata è 'TextOptions.FormattingMode' - assicurati che il valore di questa proprietà sull'oggetto che stai misurando corrisponda al valore dell'oggetto che stai rendendo (se non sono uguali). – Cameron

+4

Ho appena avuto lo stesso problema e ho appena chiamato 'textblock.Measure (new Size());' non basta. Ho dovuto usare 'textblock.Measure (new Size (double.PositiveInfinity, double.PositiveInfinity));' per ottenere un risultato per 'textblock.DesiredSize' – metacircle

+0

Ricorda che' MinWidth' deve essere impostato su 0 e 'MaxWidth 'impostato su PositiveInfinity prima della misurazione, altrimenti verrà limitato da tali valori. – zmechanic

2

La chiamata a UIElement.Measure(Size) assume come parametro Size. La seconda chiamata UIElement.DesiredSize restituisce qualsiasi valore Size passato nel metodo Measure.

Penso che questo sia il caso perché UIElement (TextBlock in questo caso) NON è un figlio di alcun controllo (ancora) e quindi DesiredSize non ha motivo di essere qualcosa di diverso.

+2

No, non necessariamente. Anche senza aggiungere UIElement (nel mio caso anche un TextBlock) a un controllo genitore, DesiredSize è stato impostato correttamente dopo aver chiamato Measure con una dimensione di availabe sufficientemente grande come parametro. – slurmomatic

0

Mi rendo conto che questa è una domanda un po 'vecchia, ma ho trovato che utilizzando il seguente codice

 TextBlock textBlock = new TextBlock(); 
     textBlock.Text = "NR valve"; 
     Size msrSize = new Size(100, 200); 
     textBlock.Measure(msrSize); 
     Size dsrdSize = textBlock.DesiredSize; 

dsrdSize viene restituito come {} 47.05,15.96. Il trucco sembra rendere msrSize più grande della dimensione effettiva prevista. msrSize sembra agire come un limite per il risultato DesiredSize(). Ad esempio, utilizzando msrSize = new Size (10, 10), restituisce un dsrdSize di {10,10} qui. Spero che questo aiuti qualcuno.

0
public static Size ShapeMeasure(TextBlock tb) { 
    // Measured Size is bounded to be less than maxSize 
    Size maxSize = new Size(
     double.PositiveInfinity, 
     double.PositiveInfinity); 
    tb.Measure(maxSize); 
    return tb.DesiredSize; 
} 

public static Testit() 
{ 
    TextBlock textBlock = new TextBlock(); 
    textBlock.Text = "NR valve"; 

    Size text size = ShapeMeasure(textBlock); 
}