Wie skaliere ich die Schriftgröße für eine Gruppe von Steuerelementen automatisch?

Ich habe ein paar TextBlocks in WPF in einem Raster, die ich abhängig von ihrer verfügbaren Breite / Höhe skalieren möchte. Als ich nach einer automatischen Skalierung der Schriftgröße suchte, war der typische Vorschlag, den TextBlock in eine ViewBox zu legen.

Also habe ich das gemacht:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Viewbox MaxHeight="18" Grid.Column="0" Stretch="Uniform" Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <TextBlock Text="{Binding Text1}" />
    </Viewbox>

    <Viewbox MaxHeight="18" Grid.Column="1" Stretch="Uniform" Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <TextBlock Text="{Binding Text2}" />
    </Viewbox>

    <Viewbox MaxHeight="18" Grid.Column="2" Stretch="Uniform" Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <TextBlock Text="{Binding Text3}" />
    </Viewbox>
</Grid>

Und es skaliert die Schriftart für jeden TextBlock automatisch. Das sieht jedoch komisch aus, denn wenn einer der TextBlocks längeren Text enthält, wird er in einer kleineren Schriftart angezeigt, während die benachbarten Rasterelemente in einer größeren Schriftart angezeigt werden. Ich möchte, dass die Schriftgröße nach Gruppen skaliert wird. Vielleicht wäre es schön, wenn ich eine "SharedSizeGroup" für eine Reihe von Steuerelementen angeben könnte, um die Schriftgröße automatisch anzupassen.

z.B.

Der erste Textblocktext könnte "26.03.2013, 10:45:30 Uhr" sein, und der zweite Textblocktext könnte "Dateiname.ext" lauten. Wenn sich diese über die Breite eines Fensters erstrecken und der Benutzer damit beginnt, das Fenster immer kleiner zu dimensionieren. Je nach Länge des Dateinamens wird die Schriftart des Datums kleiner als der Dateiname.

Wenn eines der Textfelder die Schriftgröße ändert, stimmen im Idealfall alle überein. Hat jemand eine Lösung für dieses Problem gefunden oder kann mir eine Vorstellung davon geben, wie es funktionieren würde? Wenn es benutzerdefinierten Code erfordert, können wir / ich ihn hoffentlich in eine benutzerdefinierte Mischung oder ein angefügtes Verhalten umpacken, damit er für die Zukunft wiederverwendbar ist. Ich denke, es ist ein ziemlich allgemeines Problem, aber ich konnte durch Suchen nichts darauf finden.

Aktualisieren Ich habe Mathieus Vorschlag ausprobiert und er funktioniert, aber er hat einige Nebenwirkungen:

<Window x:Class="WpfApplication6.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="270" Width="522">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Rectangle Grid.Row="0" Fill="SkyBlue" />

        <Viewbox Grid.Row="1" MaxHeight="30"  Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
                </Grid.ColumnDefinitions>

                <TextBlock Grid.Column="0" Text="SomeLongText" Margin="5" />
                <TextBlock Grid.Column="1" Text="TextA" Margin="5" />
                <TextBlock Grid.Column="2" Text="TextB" Margin="5" />

            </Grid>
        </Viewbox>
    </Grid>
</Window>

Ehrlich gesagt, das Fehlen der proportionalen Spalten ist bei mir wahrscheinlich in Ordnung. Es würde mir nichts ausmachen, die Spalten automatisch zu skalieren, um den Raum sinnvoll zu nutzen, aber es muss sich über die gesamte Breite des Fensters erstrecken.

Beachten Sie ohne maxsize, dass in diesem erweiterten Beispiel der Text zu groß ist:

<Window x:Class="WpfApplication6.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="270" Width="522">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Rectangle Grid.Row="0" Fill="SkyBlue" />

    <Viewbox Grid.Row="1"  Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
                <ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
                <ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
            </Grid.ColumnDefinitions>

            <TextBlock Grid.Column="0" Text="SomeLongText" Margin="5" />
            <TextBlock Grid.Column="1" Text="TextA" Margin="5" />
            <TextBlock Grid.Column="2" Text="TextB" Margin="5" />

        </Grid>
    </Viewbox>
</Grid>

Hier möchte ich einschränken, wie groß die Schrift werden kann, damit keine vertikalen Fensterflächen verschwendet werden.Ich erwarte, dass die Ausgabe links, mittig und rechts ausgerichtet wird, wobei die Schrift so groß wie möglich ist, bis die gewünschte maximale Größe erreicht ist.

@adabyron

Die Lösung, die Sie vorschlagen, ist nicht schlecht (und die bisher beste), weist jedoch einige Einschränkungen auf. Zum Beispiel wollte ich anfangs, dass meine Spalten proportional sind (die zweite sollte zentriert sein). Zum Beispiel könnte mein TextBlocks die beschriftenStarten, Zentrieren und Stoppen eines Diagramms wo Ausrichtung wichtig ist.

<Window x:Class="WpfApplication6.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:b="clr-namespace:WpfApplication6.Behavior"
        Title="MainWindow" Height="350" Width="525">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Rectangle Grid.Row="0" Fill="SkyBlue" />
        <Line X1="0.5" X2="0.5" Y1="0" Y2="1" Stretch="Fill" StrokeThickness="3" Stroke="Red" />

        <Grid Grid.Row="1">

            <i:Interaction.Behaviors>
                <b:MoveToViewboxBehavior />
            </i:Interaction.Behaviors>

            <Viewbox Stretch="Uniform" />
            <ContentPresenter >
                <ContentPresenter.Content>
                    <Grid x:Name="TextBlockContainer">
                        <Grid.Resources>
                            <Style TargetType="TextBlock" >
                                <Setter Property="FontSize" Value="16" />
                                <Setter Property="Margin" Value="5" />
                            </Style>
                        </Grid.Resources>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"  />
                            <ColumnDefinition Width="*"  />
                            <ColumnDefinition Width="*"  />
                            <ColumnDefinition Width="*"  />
                            <ColumnDefinition Width="*"  />
                        </Grid.ColumnDefinitions>

                        <TextBlock Grid.Column="0" Text="SomeLongText" VerticalAlignment="Center" HorizontalAlignment="Center" />
                        <TextBlock Grid.Column="2" Text="TextA" HorizontalAlignment="Center" VerticalAlignment="Center" />
                        <TextBlock Grid.Column="4" Text="TextB" HorizontalAlignment="Center" VerticalAlignment="Center" />
                    </Grid>
                </ContentPresenter.Content>
            </ContentPresenter>
        </Grid>
    </Grid>
</Window>

Und hier ist das Ergebnis. Beachten Sie, dass es nicht weiß, dass es früh abgeschnitten wird. Wenn es ViewBox ersetzt, sieht es so aus, als ob das Raster standardmäßig die Spaltengröße "Auto" hat und nicht mehr mittig ausgerichtet ist.

Antworten auf die Frage(6)

Ihre Antwort auf die Frage