首页 文章

WPF - 项目集合动态边距

提问于
浏览
0

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

enter image description here

应使用基于数据绑定值的算法计算边距 . 为了解释这个想法,让我们假设我有一个包含“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 回答

  • 1

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

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

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

相关问题