Como dimensionar automaticamente o tamanho da fonte para um grupo de controles?

Eu tenho alguns TextBlocks no WPF em uma grade que eu gostaria de escalar dependendo da largura / altura disponível. Quando eu procurei automaticamente dimensionar o tamanho da fonte, a sugestão típica é colocar o TextBlock em um ViewBox.

Então eu fiz isso:

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

E dimensiona a fonte para cada TextBlock automaticamente. No entanto, isso parece engraçado porque, se um dos TextBlocks tiver mais texto, ele estará em uma fonte menor, enquanto os elementos de grade vizinhos estarão em uma fonte maior. Eu quero o tamanho da fonte para escalar por grupo, talvez seria bom se eu pudesse especificar um "SharedSizeGroup" para um conjunto de controles para dimensionar automaticamente sua fonte.

por exemplo.

O texto dos primeiros blocos de texto pode ser "3/26/2013 10:45:30 AM" e o segundo texto TextBlocks pode indicar "FileName.ext". Se estiverem na largura de uma janela, o usuário começará a redimensionar a janela menor e menor. A data começará a tornar sua fonte menor que o nome do arquivo, dependendo do tamanho do nome do arquivo.

Idealmente, quando um dos campos de texto começar a redimensionar o tamanho do ponto da fonte, todos eles corresponderiam. Alguém veio com uma solução para isso ou pode me dar uma chance de como você faria isso funcionar? Se precisar de código personalizado, esperamos que possamos reempacotá-lo em um Blend ou Attached Behavior personalizado para que seja reutilizável no futuro. Acho que é um problema bem geral, mas não consegui encontrar nada pesquisando.

Atualizar Eu tentei a sugestão de Mathieu e isso meio que funciona, mas tem alguns efeitos colaterais:

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

Honestamente, a falta de colunas proporcionais provavelmente está bem para mim. Eu não me importaria AutoSizing as colunas para fazer uso inteligente do espaço, mas tem que abranger toda a largura da janela.

Observe sem maxsize, neste exemplo estendido o texto é muito grande:

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

Aqui, eu gostaria de limitar o tamanho que a fonte pode obter, por isso não desperdiça o espaço da janela vertical.Estou esperando que a saída seja alinhada à esquerda, ao centro e à direita, com a fonte sendo o maior possível até o tamanho máximo desejado.

@adabyron

A solução que você propõe não é ruim (E é a melhor até agora), mas tem algumas limitações. Por exemplo, inicialmente queria que minhas colunas fossem proporcionais (a segunda deveria ser centralizada). Por exemplo, meus TextBlocks podem estar rotulandoiniciar, centralizar e parar um gráfico onde o alinhamento é importante.

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

E aqui está o resultado. Observe que ele não sabe que está sendo cortado no início e, quando substitui o ViewBox, parece que o padrão Grid é o tamanho da coluna "Auto" e não alinha mais o centro.

questionAnswers(6)

yourAnswerToTheQuestion