Как автоматически масштабировать размер шрифта для группы элементов управления?
У меня есть несколько TextBlocks в WPF в сетке, которые я хотел бы масштабировать в зависимости от их ширины / высоты. Когда я искал автоматическое масштабирование размера шрифта, типичным предложением было поместить TextBlock в ViewBox.
Итак, я сделал это:
<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>
И он автоматически масштабирует шрифт для каждого TextBlock. Однако это выглядит забавно, потому что, если один из TextBlocks имеет более длинный текст, он будет иметь меньший шрифт, в то время как соседние элементы сетки будут иметь больший шрифт. Я хочу, чтобы размер шрифта масштабировался по группам, возможно, было бы неплохо, если бы я мог указать «SharedSizeGroup» для набора элементов управления для автоматического изменения размера их шрифта.
например
Первый текстовый текстовый блок может быть «26.03.2013 10:45:30», а второй текстовый текстовый блок может содержать «FileName.ext». Если они по ширине окна, и пользователь начинает изменять размер окна все меньше и меньше. Дата начнет делать свой шрифт меньше, чем имя файла, в зависимости от длины имени файла.
В идеале, как только одно из текстовых полей начнет изменять размер шрифта, все они будут совпадать. Кто-нибудь придумал решение для этого или может дать мне представление о том, как вы могли бы заставить его работать? Если для этого требуется пользовательский код, то, надеюсь, мы / я могли бы упаковать его в пользовательский Blend или Attached Behavior, чтобы его можно было использовать в будущем. Я думаю, что это довольно общая проблема, но я не смог ничего найти по ней с помощью поиска.
Обновить Я попробовал предложение Матье, и оно вроде работает, но у него есть некоторые побочные эффекты:
<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>
Честно говоря, мне не хватает пропущенных пропорциональных столбцов. Я не возражаю против автоматического изменения размеров столбцов, чтобы разумно использовать пространство, но оно должно охватывать всю ширину окна.
Обратите внимание без maxsize, в этом расширенном примере текст слишком велик:
<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>
Здесь я бы хотел ограничить размер шрифта, чтобы не тратить пространство на вертикальные окна.Я ожидаю, что выходные данные будут выровнены по левому, центральному и правому краям, причем шрифт будет максимально большим до желаемого максимального размера.
@adabyron
Решение, которое вы предлагаете, неплохое (и пока лучшее), но оно имеет некоторые ограничения. Например, изначально я хотел, чтобы мои столбцы были пропорциональными (2-й должен быть по центру). Например, мои TextBlocks могут маркироватьначало, центр и остановка графика где выравнивание имеет значение.
<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>
И вот результат. Обратите внимание, что он не знает, что он рано обрезается, а затем, когда он заменяет ViewBox, он выглядит так, как будто Grid по умолчанию имеет размер столбца «Auto» и больше не выравнивает центр.