Jak automatycznie skalować rozmiar czcionki dla grupy kontrolek?

Mam kilka TextBlocks w WPF w siatce, którą chciałbym skalować w zależności od ich dostępnej szerokości / wysokości. Kiedy szukałem automatycznego skalowania rozmiaru czcionki, typową sugestią jest umieszczenie TextBlock w ViewBox.

Zrobiłem to:

<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>

I skaluje czcionkę automatycznie dla każdego TextBlock. Wygląda to jednak śmiesznie, ponieważ jeśli jeden z TextBlocków ma dłuższy tekst, będzie miał mniejszą czcionkę, podczas gdy sąsiednie elementy siatki będą miały większą czcionkę. Chcę, aby rozmiar czcionki był skalowany według grup, być może byłoby miło, gdybym mógł określić „SharedSizeGroup” dla zestawu elementów sterujących do automatycznego rozmiaru czcionki.

na przykład

Pierwszy tekst bloków tekstowych może być „3/26/2013 10:45:30 AM”, a drugi tekst TextBlocks może powiedzieć „FileName.ext”. Jeśli są one w poprzek szerokości okna, a użytkownik zaczyna zmieniać rozmiar okna coraz mniejszy. Data zacznie zmniejszać czcionkę poniżej nazwy pliku, w zależności od długości nazwy pliku.

Idealnie, gdy jedno z pól tekstowych zacznie zmieniać rozmiar rozmiaru czcionki, wszystkie będą pasować. Czy ktoś wpadł na rozwiązanie tego problemu lub może dać mi szansę przekonania się, jak to działa? Jeśli wymaga niestandardowego kodu, mam nadzieję, że możemy go przepakować do niestandardowego zachowania Blend lub Attached Behavior, aby można było go wykorzystać w przyszłości. Myślę, że to dość ogólny problem, ale nie udało mi się znaleźć niczego, szukając.

Aktualizacja Próbowałem sugestii Mathieu i to działa, ale ma pewne skutki uboczne:

<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>

Szczerze mówiąc, brak hte proporcjonalnych kolumn jest dla mnie w porządku. Nie miałbym nic przeciwko temu, aby automatycznie dostosowywać kolumny, aby inteligentnie wykorzystać przestrzeń, ale musi ona obejmować całą szerokość okna.

Zauważ bez maksymalnego rozmiaru, w tym rozszerzonym przykładzie tekst jest zbyt duży:

<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>

Chciałbym tutaj ograniczyć wielkość czcionki, więc nie marnuje pionowego okna nieruchomości.Spodziewam się, że dane wyjściowe zostaną wyrównane do lewej, środkowej i prawej strony, a czcionka będzie tak duża, jak to możliwe, aż do pożądanego maksymalnego rozmiaru.

@adabyron

Rozwiązanie, które proponujesz, nie jest złe (i jest najlepsze), ale ma pewne ograniczenia. Na przykład początkowo chciałem, aby moje kolumny były proporcjonalne (drugie powinno być wyśrodkowane). Na przykład moje TextBlocks mogą oznaczaćpoczątek, środek i zatrzymanie wykresu gdzie wyrównanie ma znaczenie.

<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>

A oto rezultat. Zauważ, że nie wie, że jest wczepiany wcześnie, a następnie, gdy zastępuje ViewBox, wygląda na to, że Siatka domyślnie ma rozmiar kolumny „Auto” i nie wyrównuje się do środka.

questionAnswers(6)

yourAnswerToTheQuestion