我看到的针对单个项目的建议是使用TextBlock
,TextWrapping="true"
代表前者,Viewbox
代表后者。然而,两人并不能很好地融合在一起。我见过的唯一合并两者的是在Width
上明确设置[TextBlock][1]
,但这需要知道高级文本的宽度,因为不同长度的文本只能很好地解决宽度不同,不适合用于模板,因为理想的长度是可变的,事先不知道。
如果没有设置明确的宽度,我得到的是:
哪个适用于两个单字项目,但如果包裹在多行上,则多字词会更好地填充该区域。
在Width="80"
上设置TextBlock
可以很好地包装多字文本;但搞砸了单字项目的布局。
我想要的是缩放单个单词元素以适应(如顶部图像中的前两个按钮)并在缩放之前包装多个单词项以更好地利用可用空间(类似于第三个按钮)在第二个例子中 - 尽管如果3个或更多的文本可以更好地工作,则不需要将其限制为仅仅两行文本。)
我用于上述示例的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:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="150" Width="525">
<Window.Resources>
<local:MYViewModel x:Key="myVM"/>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource myVM}}">
<ItemsControl ItemsSource="{Binding ThingsList, Mode= OneWay}"
HorizontalAlignment="Stretch" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3" Rows="1"
HorizontalAlignment="Stretch" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button>
<Viewbox>
<TextBlock TextWrapping="Wrap" Text="{Binding Name}" />
</Viewbox>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
在它背后:
public class NamedThing
{
public string Name { get; set; }
}
public class MYViewModel
{
public ObservableCollection<NamedThing> ThingsList { get; set; }
= new ObservableCollection<NamedThing>
{
new NamedThing {Name = "Short"},
new NamedThing {Name = "VeryVeryLongWord"},
new NamedThing {Name = "Several Words in a Row"}
};
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
答案 0 :(得分:1)
问题是你的Viewbox可以扩展其内部的任何内容,但是TextBlocks不知道它们包含什么,只是在它们允许的范围内增长(宽度方面)(这是{默认情况下为{1}}。
第一个快速解决方案是将Infinity
(例如100)值设置为MaxWidth
。通过这种方式,多词TextBlock
将完全像单词一样反应:它会增长和缩小,但包装词不会改变。
当您了解Viewbox的工作原理时,TextBlock
的工作原因而非MaxWidth
在逻辑上是显而易见的:单个单词TextBlocks较小,因此他们的Width
较小,因此他们的成长更多一个Viewbox而不是它们的多词对应物,使它们以更大的字体显示。
扩展此解决方案,您可以将MaxWidth绑定到TextBlock的父级MaxWidth之一,以便在调整窗口大小时进行不断变换的自动换行。然后,如果您认为多字Width
没有足够的垂直空间,则可以添加一个将修改该值的转换器(例如,除以2)。
代码隐藏转换器:
TextBlock
XAML资源:
public class WidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ((double)value) / 2.0;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ((double)value) * 2.0;
}
}
MaxWidth:
<Window.Resources>
<local:MYViewModel x:Key="myVM" />
<local:WidthConverter x:Key="wc" />
</Window.Resources>
以下示例有点复杂,更多的概念验证&#39;比解决方案;我们用转换器分割多个单词,以显示模板化UniformGrid的一个槽中的每个单词;行为似乎更自然,但多字符串的布局有点粗糙。
XAML:
<TextBlock TextWrapping="Wrap"
MaxWidth="{Binding ActualWidth, Converter={StaticResource wc}, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"
Text="{Binding Name}" />
代码隐藏:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication2"
mc:Ignorable="d"
Title="MainWindow"
Height="150"
Width="525">
<Window.Resources>
<local:MYViewModel x:Key="myVM" />
<local:ThingConverter x:Key="tc" />
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource myVM}}">
<ItemsControl ItemsSource="{Binding ThingsList, Mode= OneWay}"
HorizontalAlignment="Stretch">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3"
Rows="1"
HorizontalAlignment="Stretch" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button>
<Viewbox>
<ItemsControl ItemsSource="{Binding Converter={StaticResource tc}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
TextAlignment="Center"
Text="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Viewbox>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>