none
WPF TextBox: Maximal mögliche Schriftgröße berechnen RRS feed

  • Frage

  • Hallo,

    ich habe in einem Grid mehrere Buttons und TextBoxen. Alle Controls werden automatisch in der Größe durch das MainWindow angepasst. Alle Texte sind verschieden Lang. Durch die Eigenschaft TextWrapping="Wrap" werden auch alle Texte automatisch umgebrochen. Bis hierher funktioniert alles wie es soll.

    Nun möchte ich gern, dass alle Texte in der gleichen Schriftgröße dargestellt werden aber so, dass jeweils alle Zeichen angezeigt werden.

    Meine Idee:
    1. Die maximal mögliche Schriftgröße jeder TextBox berechnen, inkl. TextWrapping.
    2. Diese Werte temporär speichern.
    3. Die kleinste Schriftgröße der temporären Werte finden.
    4. Diese gefundene kleinste Schriftgröße auf alle TextBoxen anwenden.

    Schritt 2 bis 4 ist kein Problem. Ich scheitere daran, die maximal mögliche Schriftgröße zu berechnen. Im Internet gibt es diverse Vorschläge, die aber nicht nach meinen Wünschen funktionieren.

    Mein Ansatz wäre, mit FormattedText zu arbeiten. Aber ich weiß nicht, ob das damit funktioniert.

    Ein anderer Ansatz wäre, im Code behind eine TextBox zu erstellen und diese in eine ViewBox hinzuzufügen, so dass die ViewBox den Text automatisch skaliert. Aber es scheint kein TextWrapping möglich zu sein. Dann irgendwie herausfinden, wie groß der Text in der TextBox dargestellt wird. Nur wie kommt man an die Schriftgröße ran?

    Über hilfreiche Ideen wäre ich sehr dankbar.

    Viele Grüße
    Marcel



    • Bearbeitet Celli83 Mittwoch, 12. August 2015 13:39
    Mittwoch, 12. August 2015 13:19

Antworten

Alle Antworten

  • Hallo Marcel,

    ich habe im Moment auch nur die Idee mit FormattedText die Schriftgröße Punkt für Punkt zu erhöhen bis der text nicht mehr passt.

    Ich bezweifle jedoch das sich das lohnt. In den wenigsten Fällen ist die Schriftgröße sonderlich Variabel festlegbar, erst recht nicht wenn sie trotzdem überall gleich sein sol. Ich tippe hier auf unterschiede von wenigen pt - da würde ich mir die Arbeit sparen.

    Ein Workaround mit größerem Nebeneffekt ist, dass du die Minimalgröße nimmst und dann die Größe an diese anpasst, sodass aber das selbe Seitenverhältnis vorherrscht wie beim Fenster. Dann kannst du einfach alles Prozentual per ScaleTransform hoch skalieren - damit wird dann aber wirklich alles skaliert. Nicht nur die Inhalte von TextBoxen.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Mittwoch, 12. August 2015 14:02
    Moderator
  • Hallo Tom,

    danke für die schnelle Hilfe. Ich würde es dennoch mal probieren, die Textgröße schrittweise zu erhöhen.

    Wie könnte man denn überprüfen, ob ein bestimmter Text noch in die TextBox passt? FormattedText hat keine Methode dafür oder ich hab es nicht gefunden.

    Danke und Gruß
    Marcel

    Mittwoch, 12. August 2015 14:43
  • Hallo Celli83,

    bist Du weitergekommen? 

    Gruß

    Aleksander


    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht,  kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Donnerstag, 3. September 2015 06:51
  • Hallo Aleksander,

    sorry für die späte Rückmeldung, war im Urlaub :)

    Zunächst habe ich auf Basis dieses Beispiels einen eigenen TextBlock gebastelt:

    LINK

    Dieser TextBlock hat den Vorteil, dass man die Anzahl der Zeilen mit LineCount auslesen kann. Ein weiterer Vorteil ist, dass TextWrapping dabei berücksichtigt wird.

    Mit dieser Methode versuche ich nun die maximal mögliche Schriftgröße zu ermitteln:

    private void AutoFontSize(cTextBlock textBlock, Button btn)
    {           
        int max = 100;
        for (double i = 10; i < max; i = i + 0.5)
        {
            textBlock.FontSize = i;
    
            System.Windows.Size s = MeasureTextSize(textBlock.Text, textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch, textBlock.FontSize);
                    
            double tbHeight = btn.ActualHeight;
            double fHeight = (s.Height+2) * textBlock.LineCount;
            resizeFontBtnTest.Content = textBlock.LineCount.ToString();
                    
            if (fHeight > tbHeight)
            {
                textBlock.FontSize = i-0.5;
                i = max;
            }                
        }
    }

    Der Button mit dem eigenen TextBlock sieht so aus:

    <Button Name="frageBtn" Style="{DynamicResource btnCont}" Margin="5" Grid.Row="1" SizeChanged="frageBtn_SizeChanged">
        <Grid>
            <TextBox Name="frageTxtEdit" TextWrapping="Wrap" Margin="0" Text="answer1" PreviewMouseDoubleClick="TextBoxSelectAll" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" AcceptsReturn="True" AcceptsTab="True" Background="#A5FFFFFF" BorderBrush="{x:Null}"/>
            <my:cTextBlock x:Name="frageTxt" TextWrapping="Wrap" Text="answer1" HorizontalAlignment="Center" TextAlignment="Center" VerticalAlignment="Center" SizeChanged="frageTxt_SizeChanged"/>
        </Grid>
    </Button>

    Zuletzt führe ich in der SizeChanged Methode des Buttons die AutoFontSize Methode aus:

    private void frageBtn_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        cTextBlock tbl = frageTxt;
        Grid g = (Grid)tbl.Parent;
        Button bnt = (Button)g.Parent;
    
        AutoFontSize(tbl, bnt);
    }

    Das habe ich bisher hinbekommen, leider funktioniert es nicht nach meinen Wünschen. Die Textgröße springt immer, wenn sich die größe des TextBlocks ändert.

    Wenn das TextWrapping ausgeschalten wird, dann funktioniert es soweit. Aber das Wrapping muss mit berücksichtigt werden.

    Was mache ich falsch. Wahrscheinlich gibt es eine viel bessere Lösung.

    Danke und Gruß
    Marcel

    Sonntag, 6. September 2015 10:28