我想在全宽边框内渲染几个元素,并以编程方式计算边距,以便在网格中获得具有适当边距的矩形。这将是我想要的渲染:
应使用基于数据绑定值的算法计算边距。为了解释这个想法,我们假设我有一个包含“One”,“Two”和“Three”的字符串列表,我对我的控件具有约束力。假设我的算法非常简单,并为每个下一个元素边距分配+100。所以我会有三个矩形:
所有矩形都是相同的,唯一的区别是计算的边距。
我最初的想法是使用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();
}
}
注意:当我刚运行应用程序时,它不能正确渲染矩形。但是,当我在多重绑定转换器中调试并设置断点时,应用边距并正确渲染矩形?!
我认为一般方法应该有效,但我无法弄清楚我在渲染中做错了会导致矩形以错误的边距渲染,即使它们在转换器中正确计算。
由于
答案 0 :(得分:1)
不确定我是否正确理解了您的问题,但如果您想将所有这些矩形放入相同的网格单元格中,则必须将ItemsControl的ItemsPanel设置为网格:
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
类似地,您也可以将Canvas用作ItemsPanel,并在每个项目Rectangle上设置Canvas.Left
属性(而不是Margin
)。