我在网格中的WPF中有一些TextBlocks,我想根据它们的可用宽度/高度进行缩放。当我搜索自动缩放字体大小时,典型的建议是将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”以自动调整其字体大小,那也许会很好。
e.g。
第一个文本块文本可能是“3/26/2013 10:45:30 AM”,第二个TextBlocks文本可能是“FileName.ext”。如果它们跨越窗口的宽度,则用户开始调整窗口的大小越来越小。日期将开始使其字体小于文件名,具体取决于文件名的长度。
理想情况下,一旦其中一个文本字段开始调整字体磅值大小,它们就会匹配。有没有人想出一个解决方案,或者可以让我了解你如何使它工作?如果它需要自定义代码,那么希望我们/我可以将其重新打包为自定义混合或附加行为,以便将来可以重复使用。我认为这是一个相当普遍的问题,但我无法通过搜索找到任何内容。
更新 我尝试了Mathieu的建议,但它有一些副作用:
<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>
在这里,我想限制字体的大小,因此不会浪费垂直窗口的空间。 我希望输出左,中,右对齐,Font尽可能大,直到达到所需的最大尺寸。
@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默认为列大小“Auto”并且不再对齐center。
答案 0 :(得分:29)
我想编辑我已经提供的答案,但后来认为发布新答案更有意义,因为它实际上取决于我更喜欢的要求。这可能更适合Alan的想法,因为
other one的优点是
我在StackPanel / DockPanel类型的顶级容器中测试了这个解决方案,表现得不错。
请注意,通过使用列/行宽度/高度(自动/星化),您可以获得不同的行为。因此,也可以对所有三个文本块列进行星形化,但这意味着宽度剪切确实更早发生并且有更多的余量。或者,如果网格所在的行是自动调整大小,则不会发生高度剪切。
的Xaml:
<Window x:Class="WpfApplication1.MainWindow"
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:beh="clr-namespace:WpfApplication1.Behavior"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.9*"/>
<RowDefinition Height="0.1*" />
</Grid.RowDefinitions>
<Rectangle Fill="DarkOrange" />
<Grid x:Name="TextBlockContainer" Grid.Row="1" >
<i:Interaction.Behaviors>
<beh:ScaleFontBehavior MaxFontSize="32" />
</i:Interaction.Behaviors>
<Grid.Resources>
<Style TargetType="TextBlock" >
<Setter Property="Margin" Value="5" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="SomeLongText" />
<TextBlock Grid.Column="1" Text="TextA" HorizontalAlignment="Center" />
<TextBlock Grid.Column="2" Text="TextB" HorizontalAlignment="Right" />
</Grid>
</Grid>
</Window>
ScaleFontBehavior:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Media;
using WpfApplication1.Helpers;
namespace WpfApplication1.Behavior
{
public class ScaleFontBehavior : Behavior<Grid>
{
// MaxFontSize
public double MaxFontSize { get { return (double)GetValue(MaxFontSizeProperty); } set { SetValue(MaxFontSizeProperty, value); } }
public static readonly DependencyProperty MaxFontSizeProperty = DependencyProperty.Register("MaxFontSize", typeof(double), typeof(ScaleFontBehavior), new PropertyMetadata(20d));
protected override void OnAttached()
{
this.AssociatedObject.SizeChanged += (s, e) => { CalculateFontSize(); };
}
private void CalculateFontSize()
{
double fontSize = this.MaxFontSize;
List<TextBlock> tbs = VisualHelper.FindVisualChildren<TextBlock>(this.AssociatedObject);
// get grid height (if limited)
double gridHeight = double.MaxValue;
Grid parentGrid = VisualHelper.FindUpVisualTree<Grid>(this.AssociatedObject.Parent);
if (parentGrid != null)
{
RowDefinition row = parentGrid.RowDefinitions[Grid.GetRow(this.AssociatedObject)];
gridHeight = row.Height == GridLength.Auto ? double.MaxValue : this.AssociatedObject.ActualHeight;
}
foreach (var tb in tbs)
{
// get desired size with fontsize = MaxFontSize
Size desiredSize = MeasureText(tb);
double widthMargins = tb.Margin.Left + tb.Margin.Right;
double heightMargins = tb.Margin.Top + tb.Margin.Bottom;
double desiredHeight = desiredSize.Height + heightMargins;
double desiredWidth = desiredSize.Width + widthMargins;
// adjust fontsize if text would be clipped vertically
if (gridHeight < desiredHeight)
{
double factor = (desiredHeight - heightMargins) / (this.AssociatedObject.ActualHeight - heightMargins);
fontSize = Math.Min(fontSize, MaxFontSize / factor);
}
// get column width (if limited)
ColumnDefinition col = this.AssociatedObject.ColumnDefinitions[Grid.GetColumn(tb)];
double colWidth = col.Width == GridLength.Auto ? double.MaxValue : col.ActualWidth;
// adjust fontsize if text would be clipped horizontally
if (colWidth < desiredWidth)
{
double factor = (desiredWidth - widthMargins) / (col.ActualWidth - widthMargins);
fontSize = Math.Min(fontSize, MaxFontSize / factor);
}
}
// apply fontsize (always equal fontsizes)
foreach (var tb in tbs)
{
tb.FontSize = fontSize;
}
}
// Measures text size of textblock
private Size MeasureText(TextBlock tb)
{
var formattedText = new FormattedText(tb.Text, CultureInfo.CurrentUICulture,
FlowDirection.LeftToRight,
new Typeface(tb.FontFamily, tb.FontStyle, tb.FontWeight, tb.FontStretch),
this.MaxFontSize, Brushes.Black); // always uses MaxFontSize for desiredSize
return new Size(formattedText.Width, formattedText.Height);
}
}
}
VisualHelper:
public static List<T> FindVisualChildren<T>(DependencyObject obj) where T : DependencyObject
{
List<T> children = new List<T>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
var o = VisualTreeHelper.GetChild(obj, i);
if (o != null)
{
if (o is T)
children.Add((T)o);
children.AddRange(FindVisualChildren<T>(o)); // recursive
}
}
return children;
}
public static T FindUpVisualTree<T>(DependencyObject initial) where T : DependencyObject
{
DependencyObject current = initial;
while (current != null && current.GetType() != typeof(T))
{
current = VisualTreeHelper.GetParent(current);
}
return current as T;
}
答案 1 :(得分:9)
将您的网格放在ViewBox中,这将缩放整个网格:
<Viewbox Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Text1}" Margin="5" />
<TextBlock Grid.Column="1" Text="{Binding Text2}" Margin="5" />
<TextBlock Grid.Column="2" Text="{Binding Text3}" Margin="5" />
</Grid>
</Viewbox>
答案 2 :(得分:1)
我想我知道要走的路,将剩下的留给你。在这个例子中,我使用转换器将FontSize绑定到TextBlock的ActualHeight(转换器在下面):
<Window x:Class="MyNamespace.Test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Converters="clr-namespace:UpdateYeti.Converters"
Title="Test" Height="570" Width="522">
<Grid Height="370" Width="522">
<Grid.Resources>
<Converters:HeightToFontSizeConverter x:Key="conv" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Fill="SkyBlue" />
<Grid Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinHeight="60" Background="Beige">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="SomeLongText" Margin="5"
FontSize="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight, Converter={StaticResource conv}}" />
<TextBlock Grid.Column="1" Text="TextA" Margin="5" HorizontalAlignment="Center"
FontSize="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight, Converter={StaticResource conv}}" />
<TextBlock Grid.Column="2" Text="TextB" Margin="5" FontSize="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight, Converter={StaticResource conv}}" />
</Grid>
</Grid>
</Window>
[ValueConversion(typeof(double), typeof(double))]
class HeightToFontSizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// here you can use the parameter that you can give in here via setting , ConverterParameter='something'} or use any nice login with the VisualTreeHelper to make a better return value, or maybe even just hardcode some max values if you like
var height = (double)value;
return .65 * height;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
答案 3 :(得分:1)
一般注释:整个文本缩放的一种可能替代方法是在TextBlocks上使用TextTrimming。
我很难找到解决方案。使用视图框很难与任何布局调整混合使用。最糟糕的是,ActualWidth等不会在视图框内发生变化。所以我最终决定只在绝对必要时才使用视图,这就是剪切发生的时候。因此,我在ContentPresenter和Viewbox之间移动内容,具体取决于可用空间。
这个解决方案并不像我想的那样通用,主要是MoveToViewboxBehavior确实假设它附加到具有以下结构的网格。如果无法容纳,则很可能必须调整行为。创建用户控件并表示必要的部分(PART _...)可能是一个有效的替代方案。
请注意,我已将网格的列从三个扩展到五个,因为这使得解决方案变得更加容易。这意味着中间文本块在绝对坐标意义上不会完全位于中间,而是在左右两侧的文本块之间居中。
<Grid > <!-- MoveToViewboxBehavior attached to this grid -->
<Viewbox />
<ContentPresenter>
<ContentPresenter.Content>
<Grid x:Name="TextBlockContainer">
<TextBlocks ... />
</Grid>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
的Xaml:
<Window x:Class="WpfApplication1.MainWindow"
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:beh="clr-namespace:WpfApplication1.Behavior"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Fill="SkyBlue" />
<Grid Grid.Row="1">
<i:Interaction.Behaviors>
<beh: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="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="SomeLongText" />
<TextBlock Grid.Column="2" Text="TextA" />
<TextBlock Grid.Column="4" Text="TextB" />
</Grid>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
</Grid>
</Window>
MoveToViewBoxBehavior:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Media;
using WpfApplication1.Helpers;
namespace WpfApplication1.Behavior
{
public class MoveToViewboxBehavior : Behavior<Grid>
{
// IsClipped
public bool IsClipped { get { return (bool)GetValue(IsClippedProperty); } set { SetValue(IsClippedProperty, value); } }
public static readonly DependencyProperty IsClippedProperty = DependencyProperty.Register("IsClipped", typeof(bool), typeof(MoveToViewboxBehavior), new PropertyMetadata(false, OnIsClippedChanged));
private static void OnIsClippedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var beh = (MoveToViewboxBehavior)sender;
Grid grid = beh.AssociatedObject;
Viewbox vb = VisualHelper.FindVisualChild<Viewbox>(grid);
ContentPresenter cp = VisualHelper.FindVisualChild<ContentPresenter>(grid);
if ((bool)e.NewValue)
{
// is clipped, so move content to Viewbox
UIElement element = cp.Content as UIElement;
cp.Content = null;
vb.Child = element;
}
else
{
// can be shown without clipping, so move content to ContentPresenter
cp.Content = vb.Child;
vb.Child = null;
}
}
protected override void OnAttached()
{
this.AssociatedObject.SizeChanged += (s, e) => { IsClipped = CalculateIsClipped(); };
}
// Determines if the width of all textblocks within TextBlockContainer (using MaxFontSize) are wider than the AssociatedObject grid
private bool CalculateIsClipped()
{
double totalDesiredWidth = 0d;
Grid grid = VisualHelper.FindVisualChildByName<Grid>(this.AssociatedObject, "TextBlockContainer");
List<TextBlock> tbs = VisualHelper.FindVisualChildren<TextBlock>(grid);
foreach (var tb in tbs)
{
if (tb.TextWrapping != TextWrapping.NoWrap)
return false;
totalDesiredWidth += MeasureText(tb).Width + tb.Margin.Left + tb.Margin.Right + tb.Padding.Left + tb.Padding.Right;
}
return Math.Round(this.AssociatedObject.ActualWidth, 5) < Math.Round(totalDesiredWidth, 5);
}
// Measures text size of textblock
private Size MeasureText(TextBlock tb)
{
var formattedText = new FormattedText(tb.Text, CultureInfo.CurrentUICulture,
FlowDirection.LeftToRight,
new Typeface(tb.FontFamily, tb.FontStyle, tb.FontWeight, tb.FontStretch),
tb.FontSize, Brushes.Black);
return new Size(formattedText.Width, formattedText.Height);
}
}
}
VisualHelper:
public static class VisualHelper
{
public static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
{
T child = null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
var o = VisualTreeHelper.GetChild(obj, i);
if (o != null)
{
child = o as T;
if (child != null) break;
else
{
child = FindVisualChild<T>(o); // recursive
if (child != null) break;
}
}
}
return child;
}
public static List<T> FindVisualChildren<T>(DependencyObject obj) where T : DependencyObject
{
List<T> children = new List<T>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
var o = VisualTreeHelper.GetChild(obj, i);
if (o != null)
{
if (o is T)
children.Add((T)o);
children.AddRange(FindVisualChildren<T>(o)); // recursive
}
}
return children;
}
public static T FindVisualChildByName<T>(DependencyObject parent, string name) where T : FrameworkElement
{
T child = default(T);
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var o = VisualTreeHelper.GetChild(parent, i);
if (o != null)
{
child = o as T;
if (child != null && child.Name == name)
break;
else
child = FindVisualChildByName<T>(o, name);
if (child != null) break;
}
}
return child;
}
}
答案 4 :(得分:1)
您可以在ViewBox中使用隐藏的ItemsControl。
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Viewbox VerticalAlignment="Bottom">
<Grid>
<TextBlock Text="SomeLongText"/>
<ItemsControl Visibility="Hidden">
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
<TextBlock Text="SomeLongText"/>
<TextBlock Text="TextA"/>
<TextBlock Text="TextB"/>
</ItemsControl>
</Grid>
</Viewbox>
<Viewbox Grid.Column="1" VerticalAlignment="Bottom">
<Grid>
<TextBlock Text="TextA"/>
<ItemsControl Visibility="Hidden">
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
<TextBlock Text="SomeLongText"/>
<TextBlock Text="TextA"/>
<TextBlock Text="TextB"/>
</ItemsControl>
</Grid>
</Viewbox>
<Viewbox Grid.Column="2" VerticalAlignment="Bottom">
<Grid>
<TextBlock Text="TextB"/>
<ItemsControl Visibility="Hidden">
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
<TextBlock Text="SomeLongText"/>
<TextBlock Text="TextA"/>
<TextBlock Text="TextB"/>
</ItemsControl>
</Grid>
</Viewbox>
</Grid>
或
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Viewbox VerticalAlignment="Bottom">
<Grid>
<TextBlock Text="{Binding Text1}"/>
<ItemsControl Visibility="Hidden" ItemsSource="{Binding AllText}">
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Viewbox>
<Viewbox Grid.Column="1" VerticalAlignment="Bottom">
<Grid>
<TextBlock Text="{Binding Text2}"/>
<ItemsControl Visibility="Hidden" ItemsSource="{Binding AllText}">
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Viewbox>
<Viewbox Grid.Column="2" VerticalAlignment="Bottom">
<Grid>
<TextBlock Text="{Binding Text3}"/>
<ItemsControl Visibility="Hidden" ItemsSource="{Binding AllText}">
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Viewbox>
</Grid>
答案 5 :(得分:0)
解决方案可能是这样的:
选择maxFontSize,然后使用线性方程式,考虑当前Window,定义要显示的相应FontSize。窗口的高度或宽度将限制最终的FontSize选择。
让我们来看一个&#34;单一种类TextBlock&#34;对于整个网格:
Window.Current.SizeChanged += (sender, args) =>
{
int minFontSize = a;
int maxFontSize = b;
int maxMinFontSizeDiff = maxFontSize - minFontSize;
int gridMinHeight = c;
int gridMaxHeight = d;
int gridMaxMinHeightDiff = gridMaxHeight - gridMinHeight;
int gridMinWidth = e;
int gridMaxWidth = f;
int gridMaxMinHeightDiff = gridMaxWidth - gridMaxWidth;
//Linear equation considering "max/min FontSize" and "max/min GridHeight/GridWidth"
double heightFontSizeDouble = (maxMinFontSizeDiff / gridMaxMinHeightDiff ) * Grid.ActualHeight + (maxFontSize - (gridMaxHeight * (maxMinFontSizeDiff / gridMaxMinHeightDiff)))
double widthFontSizeDouble = (maxMinFontSizeDiff / gridMaxMinWidthDiff ) * Grid.ActualWidth + (maxFontSize - (gridMaxWidth * (maxMinFontSizeDiff / gridMaxMinWidthDiff)))
int heightFontSize = (int)Math.Round(heightFontSizeDouble)
int widthFontSize = (int)Math.Round(widthFontSizeDouble)
foreach (var children in Grid.Children)
{
(children as TextBlock).FontSize = Math.Min(heightFontSize, widthFontSize);
}
}