2012-03-20 7 views
7

Sto cercando di ottenere un comportamento specifico su TextBlock in modo che la sua altezza includa solo l'altezza delle lettere maiuscole (dalla linea di base alla cima meno "altezza del montante") . Si prega di vedere l'immagine Sphinx da Wikipedia per vedere cosa intendo. Anche l'immagine qui sotto potrebbe indicare meglio ciò che sto cercando.TextBlock grande come una lettera maiuscola (ignorando il carattere ascender/discendente)

Sample enter image description here

Non sto specificamente alla ricerca di una soluzione di puro XAML (probabilmente impossibile) quindi un codice C# dietro (un convertitore) è anche bene.

Questo è l'XAML utilizzato in XamlPad per produrre la A sinistra nell'immagine sopra.

<TextBlock Text="A" Background="Aquamarine" FontSize="120" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
+0

È necessario utilizzare MeasureString o una tecnica simile. Guarda questa domanda http://stackoverflow.com/questions/824281/wpf-equivalent-to-textrenderer –

risposta

1

Aggiornato:

Se ho capito bene, ci sono alcuni trucchi che conosco per questo,

Puoi Scale con RenderTransform che di solito è il modo più efficiente;

<TextBlock Text="Blah"> 
    <TextBlock.RenderTransform> 
    <CompositeTransform ScaleY="3"/> 
    </TextBlock.RenderTransform> 
</TextBlock> 

Oppure è possibile incorporare il TextBlock in un Viewbox a "zoom" il testo per adattarsi i limiti del suo contenitore se per esempio si imposta i valori di altezza duri sulle righe della griglia come;

<Grid> 
<Grid.RowDefinitions> 
<RowDefinition Height="120"/> 
<RowDefinition Height="120"/> 
</Grid.RowDefinitions> 
<Viewbox VerticalAlignment="Stretch" Height="Auto"> 
     <!-- The textblock and its contents are 
     stretched to fill its parent --> 
     <TextBlock Text="Sphinx" /> 
</Viewbox> 
<Viewbox Grid.Row="2" VerticalAlignment="Stretch" Height="Auto"> 
     <!-- The textblock and its contents are 
     stretched to fill its parent --> 
     <TextBlock Text="Sphinx2" /> 
</Viewbox> 

oppure è possibile associare lo a un elemento Contenitore come;

<Grid x:Name="MyText" Height="120"> 
<TextBlock FontSize="{Binding ElementName=MyText, Path=Height}" Text="Sphinx" /> 
</Grid> 

Potrebbero presentare l'effetto che cerchi?

+0

Hm ... non proprio. Non vedo alcun effetto nel tuo primo XAML. Il secondo ha un ".Valore" in più ma continua a non farlo. Grazie comunque. Ho aggiunto una nuova immagine per spiegare ulteriormente. Mi sto avvicinando a inchiodare questo con un convertitore personalizzato e multibinding. Non è carino però. Stavo cercando una soluzione semplice. – wpfwannabe

+0

Beh, ho provato a fare una modifica e non mi permette di salvare dicendo che i post non possono contenere quel contenuto?Che è una cosa strana senza spiegazioni, ma penso che quello che vuoi fare è usare GlyphTypeFace per trovare il valore di altezza della linea e impostarlo senza che il tuo interlinea (principale) guardi più avanti se ho tempo da tempo Im curioso a, mai avuto un motivo per fare confusione con i caratteri in questo modo prima. –

+0

Grazie! Dopo tutto, ho funzionato come volevo. Se nessuno trova una soluzione come esercizio, pubblicherò la mia risposta tra un paio di giorni. – wpfwannabe

4

Si può provare a utilizzare l'attributo LineStackingStrategy = "BlockLineHeight" e un convertitore sugli attributi LineHeight e un convertitore sull'altezza di TextBlock. Questo è un esempio di codice di convertitori

// Height Converter 
public class FontSizeToHeightConverter : IValueConverter 
{ 
    public static double COEFF = 0.715; 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return (double)value * COEFF; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
// LineHeightConverter 
public class FontSizeToLineHeightConverter : IValueConverter 
{ 
    public static double COEFF = 0.875; 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return double.Parse(value.ToString()) * COEFF; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

il coefficiente utilizzato sui convertitori dipende Usato familiari Fonts (Baseline e interlinea):

<TextBlock Text="ABC" Background="Aqua" LineStackingStrategy="BlockLineHeight" 
FontSize="{Binding ElementName=textBox1, Path=Text}" 
FontFamily="{Binding ElementName=listFonts, Path=SelectedItem}" 
Height="{Binding RelativeSource={RelativeSource Self}, Path=FontSize, Mode=OneWay, Converter={StaticResource FontSizeToHeightConverter1}}" 
LineHeight="{Binding RelativeSource={RelativeSource Self}, Path=FontSize, Converter={StaticResource FontSizeToLineHeightConverter}}"/> 

sample with params Coeff = 0.7

La soluzione migliore è quella di trovare il modo per calcolare il Coeff in base ai parametri Baseline e LineSpacing di FontFamily. In questo esempio (UI Segeo) Coeff of Height = 0.715 e LineHeight = 0,875 * FontSize.

Problemi correlati