2

问题:一个带有 ItemsControl 和一些项目的窗口(比如说矩形)。窗口设置了 MinWidth 和 MinHeight(例如 300),如果矩形没有足够的空间显示以显示在 2 列中,我需要在调整窗口大小时使用它。如果在 2 列中仍然没有足够的空间来显示滚动查看器。

我尝试过: 1. 创建一个扩展的 ItemsControl:

<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <local:MyGrid IsItemsHost="True" x:Name="PART_ItemsPanel" Initialized="OnItemsPanelInitialized" CanVerticallyScroll="True" CanHorizontallyScroll="True">
            <local:MyGrid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </local:MyGrid.ColumnDefinitions>
            <local:MyGrid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
            </local:MyGrid.RowDefinitions>
        </local:MyGrid>
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

我的 ItemsControl 作为 ItemsPanelTemplate 有一个扩展网格:

公共类 MyGrid :网格,IScrollInfo { ....IScrollInfo 实现 }

我使用这个网格认为当 ItemsControl 将 PrepareContainerForItemOverride() 时,我可以使用它来将项目拆分为两列。

这个想法是从会议中“采取”的......但我不知道下一步该做什么......我有这样的问题:当我为数据网格覆盖测量和排列时,我在 DataGrid 中设置了项目的位置,但是然后它被称为 PrepareContainerForItemOverride()...然后呢?我应该计算我应该做的行数?但是如果然后我再次调整窗口大小... PrepareContainerForItemOverride() 将不会被调用...

这个问题已经解决了我......如果你们中的一些人有一个线索,请给我一个线索。感谢你们!

4

2 回答 2

0

我想分享我采取的解决方案……如果有人需要的话。

为了避免 IScrollInfo 的实现,我用 ListBox 控件更改了 ItemsControl。所以我仍然要覆盖 Arrange。在排列中,我计算了第一列的项目高度,并在 GridPanel 中排列项目。我使用调度程序,因为 scrollViewer 排列并不总是有效的,我指望它来获得可见高度。

<ListBox x:Uid="allListBox" x:Name="adminListBoxControl" ItemTemplate ="{DynamicResource LinkButtonItemTemplate}" Margin="15" BorderBrush="Transparent" Background="Transparent">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <local:GridPanel>
                        <local:GridPanel.ColumnDefinitions>
                            <ColumnDefinition Width="0.45*"/>
                            <ColumnDefinition Width="0.45*"/>
                            <ColumnDefinition Width="0.1*"/>
                        </local:GridPanel.ColumnDefinitions>
                        <local:GridPanel.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                        </local:GridPanel.RowDefinitions>
                    </local:GridPanel>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>

protected override Size ArrangeOverride(Size finalSize)
    {
       Size arrangeSize = base.ArrangeOverride(finalSize);

        lastItemInFirstColumn = -1;
        double totalHeight = 0;

        DispatcherPriority p = ScrollViewer.IsArrangeValid ? DispatcherPriority.Normal : DispatcherPriority.Input;
        if (o != null)
            o.Abort();

        o = Dispatcher.BeginInvoke(p, (Action)(() =>
        {
            double fitHeight = ScrollViewer.ActualHeight;
            foreach (UIElement child in this.InternalChildren)
            {
                if (totalHeight + child.DesiredSize.Height < fitHeight)
                {
                    totalHeight += child.DesiredSize.Height;
                    lastItemInFirstColumn++;
                }
                else
                {
                    if (lastItemInFirstColumn + 1 < InternalChildren.Count - (lastItemInFirstColumn + 1))
                        lastItemInFirstColumn++;
                    break;
                }
            }

            //set items positions
            ArrangeItemsInGrid();
        }));

        o.Completed += (s, e) => { o = null; };
        return arrangeSize;
    }
于 2011-11-16T07:47:13.937 回答
0

在我看来,您所需要的只是您的ItemsControl. 可能你会使用内置的WrapPanel,但你也可以编写自己的:

<ItemsControl ...>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <!-- put whatever panel that encapsulates your layout logic here, possibly your own -->
            <WrapPanel/>
        </ItemsPanelTemplate>
    <ItemsControl.ItemsPanel>
</ItemsControl>
于 2011-11-11T07:33:51.907 回答