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:Grid、IScrollInfo{....IScrollInfo実装}

私はこのグリッドを使用して、ItemsControlがPrepareContainerForItemOverride()を実行するときに、これを使用してアイテムを2つの列に分割できると考えています。

アイデアは会議から「取得」されます....しかし、次に何をすべきかわかりません...次のような質問があります:データグリッドの測定と配置をオーバーライドするとき、データグリッドでアイテムの位置を設定しますが、それからそれはPrepareContainerForItemOverride()と呼ばれます...それでは何ですか?作成する行数を計算する必要がありますか?しかし、その後、ウィンドウのサイズを再度変更すると、PrepareContainerForItemOverride()は呼び出されません...

この問題は私を超えています...あなたの誰かがそれを持っているなら私に手がかりを教えてください。君たちありがとう!

4

2 に答える 2

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 に答える
0

私が取った解決策を共有したかった...誰かがそれを必要とするなら。

IScrollInfoの実装を回避するために、ItemsControlをListBoxコントロールに変更しました。したがって、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 に答える