我想创建一个绑定到对象列表的水平布局,并显示一些信息。我希望此控件中控件的大小可以填充控件,就像UniformGrid一样。 问题是,我不希望控件的宽度均匀分布,而是基于对象本身的属性进行加权。
我认为使用自定义ItemsPanelTemplate的ItemsControl是一个很好的策略,因为它可以与UniformGrid一起使用:
<ItemsControl x:Name="itemsControl" ItemsSource="{Binding MyResults}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock Width="{Binding Weight}" Text="{Binding Weight}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
绑定到视图模型:
public class MainViewModel : PropertyChangedBase
{
public List<MyTestClass> MyResults { get; set; } = new List<MyTestClass>()
{
new MyTestClass() { Weight = 25 },
new MyTestClass() { Weight = 50 },
new MyTestClass() { Weight = 25 }
};
}
public class MyTestClass
{
public int Weight { get; set; }
}
一个想法是切换到普通网格并使用ColumnDefinitions * -width行为(如(25*,50*,25*)
但绑定为Weight*
),但我无法弄清楚如何做到这一点。 / p>
答案 0 :(得分:2)
使用自定义Panel
实现这会更容易。我会选择这样的东西:
public class WeightedPanel : Panel
{
public static double GetWeight(DependencyObject obj)
{
return (double)obj.GetValue(WeightProperty);
}
public static void SetWeight(DependencyObject obj, double value)
{
obj.SetValue(WeightProperty, value);
}
public static readonly DependencyProperty WeightProperty =
DependencyProperty.RegisterAttached("Weight", typeof(double), typeof(WeightedPanel), new PropertyMetadata(1.0));
private double totalWeight_;
protected override Size MeasureOverride(Size availableSize)
{
totalWeight_ = 0;
foreach (UIElement child in InternalChildren)
{
totalWeight_ += WeightedPanel.GetWeight(child);
child.Measure(availableSize);
}
return new Size(0, 0);
}
protected override Size ArrangeOverride(Size finalSize)
{
double offset = 0;
foreach (UIElement child in InternalChildren)
{
var weight = WeightedPanel.GetWeight(child);
var width = finalSize.Width * weight / totalWeight_;
child.Arrange(new Rect(new Point(offset, 0), new Size(width, finalSize.Height)));
offset += width;
}
return finalSize;
}
}
用法
<local:WeightedPanel>
<Border local:WeightedPanel.Weight="25" Background="Green"></Border>
<Border local:WeightedPanel.Weight="50" Background="Red"></Border>
<Border local:WeightedPanel.Weight="25" Background="Blue"></Border>
</local:WeightedPanel>
答案 1 :(得分:-1)
UniformGrid提供了一种在网格中排列内容的方法,其中网格中的所有单元格具有相同的大小。 我用WrapPanel尝试了你的例子,我认为结果就是你需要的。 所以只需将UniformGrid更改为WrapPanel或StackPanel(Orientation =&#34; Horizontal&#34;)。 请参见截图 WrapPanel