我想在全宽边框内渲染几个元素,并以编程方式计算边距,以便在网格中获得具有适当边距的矩形 . 这将是我想要的渲染:
应使用基于数据绑定值的算法计算边距 . 为了解释这个想法,让我们假设我有一个包含“One”,“Two”和“Three”的字符串列表,这些字符串与我的控件绑定 . 假设我的算法非常简单,并为每个下一个元素边距分配100 . 所以我会有三个矩形:
-
元素的矩形"One" - 边距:100
-
元素的矩形"Two" - 边距:200
-
元素的矩形"Three" - 边距:300
所有矩形都是相同的,唯一的区别是计算的边距 .
我最初的想法是使用ItemsControl并使用MultiBinding来计算每个元素的边距 .
但是,当我使用带有MultiBinding的ItemsControl来计算动态边距时,我无法正确渲染矩形 .
<ItemsControl>
<ItemsControl.ItemsSource>
<x:Array Type="sys:String"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String>One</sys:String>
<sys:String>Two</sys:String>
<sys:String>Three</sys:String>
</x:Array>
</ItemsControl.ItemsSource>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Rectangle Name="InnerRectangle" VerticalAlignment="Stretch" Fill="Blue" Width="2" Height="120">
<Rectangle.Margin>
<MultiBinding Mode="OneWay" Converter="{StaticResource MultiMarginConverter}">
<Binding Path="ActualWidth" RelativeSource="{RelativeSource AncestorType={x:Type Border}}"></Binding>
<Binding Path=""></Binding>
</MultiBinding>
</Rectangle.Margin>
</Rectangle>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
如果我运行它,边距在转换器中正确计算,但矩形呈现为堆叠在彼此之上?
计算边距的算法将使用当前上下文中的几个值,因此我需要使用多个属性值,这就是我使用多重绑定的原因 .
为了尝试这个概念,这里的转换器只是为了获得一些动态余量:
public class MultiBindingMarginConverter : IMultiValueConverter
{
List<Double> margins = new List<Double>() { 110, 220, 333, 444, 555, 666, 777 };
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var randomizer = new Random();;
// I just get a random margin to try the concept. The margin will be computed by a more complex algorithm
var computedMargin = margins.ElementAt(randomizer.Next(1, 7));
return new Thickness(computedMargin, 0, 0, 0);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
注意:当我刚运行应用程序时,它不能正确渲染矩形 . 但是,当我在多重绑定转换器中调试并设置断点时,应用边距并正确呈现矩形?!
我认为一般方法应该有效,但我无法弄清楚我在渲染中做错了会导致矩形以错误的边距渲染,即使它们在转换器中正确计算 .
谢谢
1 回答
不确定我是否正确理解了您的问题,但是如果您想将所有这些矩形放入同一个Grid单元格中,则必须将ItemsControl的ItemsPanel设置为Grid:
类似地,您也可以使用Canvas作为ItemsPanel并在每个项目Rectangle上设置
Canvas.Left
属性(而不是Margin
) .