У меня есть несколько текстовых блоков в 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>
И он автоматически масштабирует шрифт для каждого текстового блока. Однако это выглядит забавно, потому что если один из TextBlocks имеет более длинный текст, то он будет иметь меньший шрифт, в то время как соседние элементы сетки будут иметь больший шрифт. Я хочу, чтобы размер шрифта масштабировался по группам, возможно, было бы неплохо, если бы я мог указать "SharedSizeGroup" для набора элементов управления для автоматического размера шрифта.
например.
В первом текстовом блоке текст может быть "3/26/2013 10:45:30 AM", а второй текст TextBlocks может содержать "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>
Честно говоря, отсутствующие пропорциональные столбцы hte, вероятно, прекрасны для меня. Я бы не возражал против AutoSize столбцов для интеллектуального использования пространства, но он должен охватывать всю ширину окна.
Обратите внимание, что без 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
Решение, которое вы предлагаете, неплохо (и это еще лучше), но оно имеет некоторые ограничения. Например, изначально мне хотелось, чтобы мои столбцы были пропорциональными (второй должен быть центрирован). Например, мои 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 по умолчанию имеет размер столбца "Авто" и больше не выравнивает центр.