也许你们可以帮我解决这个问题:我有一个字典和一个绑定到该字典的 ItemsControl。每个条目的 Key 决定了 ItemsControl 中每个 Item 的内容,而 Value 决定了每个 Item 的宽度。最大的问题是:宽度是一个百分比值,所以它告诉我,例如,我的 Item 的大小需要是其父项的 20%。
我怎样才能做到这一点?我知道网格能够使用基于星的宽度,但由于我必须在网格的开头定义 GridDefinition,因此我无法在 ItemsControl.ItemTemplate 中执行此操作。
当前代码:
<ItemsControl ItemsSource="{Binding Distribution}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid IsItemsHost="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- I NEED THIS TO BE A CERTAIN PERCENTAGE IN WIDTH -->
<Label Content="{Binding Key.Text}" Foreground="{Binding Key.Color}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
对此有什么想法吗?有什么优雅的方法可以解决这个问题吗?
谢谢!
澄清:百分比应该基于 ItemControls 父级!
还有一个:每个项目都应该是网格的一列,而不是一行。所以我需要所有项目在同一行中彼此相邻。
解决方案:
感谢您的帮助,这个问题可以通过使用 Multibinding 和 Binding 到 ItemsControl 的 ActualWidth 来解决。这样,每当 ItemsControl 的大小发生变化时,Items 也会发生变化。不需要网格。这个解决方案只创建一个相对宽度,但同样的解决方案当然可以应用于项目的高度。这是一个简短的版本,更全面的解释见下文:
XAML:
<ItemsControl ItemsSource="{Binding Distribution}" Name="itemsControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True" Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Key.Text}"
Foreground="{Binding Key.Color}">
<Label.Width>
<MultiBinding Converter="{StaticResource myConverter}">
<Binding Path="Value"/>
<Binding Path="ActualWidth" ElementName="itemsControl"/>
</MultiBinding>
</Label.Width>
</Label>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
转换器:
class MyConverter : IMultiValueConverter
{
public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
{
//[1] contains the ItemsControl.ActualWidth we binded to, [0] the percentage
//In this case, I assume the percentage is a double between 0 and 1
return (double)value[1] * (double)value[0];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
这应该可以解决问题!