设置 ItemsControl Children 的宽度和高度

Set Width and Height of ItemsControl Children

我的 CustomItemsControl 如下所示:

   <local:CustomItemsControl x:Name="CustomItemsControl" >
        <local:CustomItemsControl.ItemTemplate>
            <DataTemplate>
                <Border x:Name="rectangle" Background="Orange" CornerRadius="5"  />
            </DataTemplate>
        </local:CustomItemsControl.ItemTemplate>
    </local:CustomItemsControl>

根据我的 CustomItemsControl 包含的项目数量,它应该计算 "Container" 个项目的宽度和高度。

我想我可以通过调用项目的方法 Measure/Arrange 来实现。但是我的代码似乎对项目的大小没有任何影响((实际)宽度或(实际)高度为 NaN 或 0)

public class CustomItemsControl : ItemsControl
{
    protected override Size MeasureOverride(Windows.Foundation.Size availableSize)
    {
        Windows.Foundation.Size size = base.ArrangeOverride(availableSize);
        if (ItemsSource != null)
        {
            double CellWidth = size.Width / Items.Count;
            foreach (var Item in Items)
            {
                DependencyObject Container = ContainerFromItem(Item);
                if(Container!=null)
                {
                    FrameworkElement Element = Container as FrameworkElement;
                    //Element.Width = CellWidth; 
                    //Element.Height = CellWidth; 
                    Element.Measure(new Size(CellWidth, CellWidth));
                    Element.Arrange(new Rect(0, 0, CellWidth, CellWidth));
                }

            }
        }
        return size;
    }
}

除非您设置边框的宽度和高度(例如 10),否则项目不会显示。我试图完成我的 CustomItemsControl 计算项目的宽度和高度。我做错了什么?我怎样才能完成我的计划?

您应该编写一个适当的自定义 Panel 并覆盖 MeasureOverrideArrangeOverride 方法并将其分配给 ItemsControl 的 ItemsPanel 属性:

<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <local:CustomPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border ... />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

CustomPanel class 可能如下所示。该控件水平排列其子元素。它可以像 StackPanel 一样用 Orientation 属性 扩展,以水平或垂直排列其子项。

public class CustomPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        var size = new Size();

        if (double.IsInfinity(availableSize.Width)) // availableSize may be infinite
        {
            availableSize.Width = RenderSize.Width;
        }

        if (Children.Count > 0)
        {
            var cellWidth = availableSize.Width / Children.Count;
            var childSize = new Size(cellWidth, cellWidth);

            foreach (var child in Children)
            {
                child.Measure(childSize);
            }

            size.Width = availableSize.Width;
            size.Height = cellWidth;
        }

        return size;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        var size = new Size();

        if (Children.Count > 0)
        {
            var cellWidth = finalSize.Width / Children.Count;
            var childRect = new Rect(0, 0, cellWidth, cellWidth);

            foreach (var child in Children)
            {
                child.Arrange(childRect);
                childRect.X += cellWidth;
            }

            size.Width = finalSize.Width;
            size.Height = cellWidth;
        }

        return size;
    }
}