WPF - 项目集合动态边距

时间:2013-04-15 19:48:34

标签: c# wpf xaml

我想在全宽边框内渲染几个元素,并以编程方式计算边距,以便在网格中获得具有适当边距的矩形。这将是我想要的渲染:

enter image description here

应使用基于数据绑定值的算法计算边距。为了解释这个想法,我们假设我有一个包含“One”,“Two”和“Three”的字符串列表,我对我的控件具有约束力。假设我的算法非常简单,并为每个下一个元素边距分配+100。所以我会有三个矩形:

  • 元素的矩形“一” - 边距:100
  • 元素的矩形“两个” - 边距:200
  • 元素的矩形“三” - 边距: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 个答案:

答案 0 :(得分:1)

不确定我是否正确理解了您的问题,但如果您想将所有这些矩形放入相同的网格单元格中,则必须将ItemsControl的ItemsPanel设置为网格:

<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <Grid/>
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

类似地,您也可以将Canvas用作ItemsPanel,并在每个项目Rectangle上设置Canvas.Left属性(而不是Margin)。