0

我有一个停靠面板,我使用 ItemsControl 动态填充面板来填充面板。停靠面板需要 itemscontrol 列表中的最后一个子项来填充面板的其余部分,但如果我以这种方式填充它似乎不会发生......我该怎么做才能让最后一个项目展开?

我如何设置它的片段:(注意我将停靠面板背景设置为蓝色,以便我可以将填充的用户控件与面板背景区分开来)

        <DockPanel Background="Blue" LastChildFill="True" Margin="0">
        <ItemsControl ItemsSource="{Binding Requirements}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <local:TMGrid2View Baseline="{Binding}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </DockPanel>

我目前关于正在发生的事情的假设是子填充被应用于 itemscontrol,而不是填充在 itemscontrol 中的子项。例如,我过去使用过设置器来指定孩子应该停靠在面板的一侧......但似乎没有一个子设置器选项可以让它扩展......

4

4 回答 4

9

不要ItemsControlDockPanel; 把. DockPanel_ ItemsControl使用 将ItemsPanelTemplateItemsControl项目放置在DockPanel.

使用ItemContainerStyle来设置DockPanel.Dock项目容器的属性(对于ItemsControl,将是ContentPresenters)。

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <ItemsControl Margin="5">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <DockPanel LastChildFill="True"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
      <Style TargetType="ContentPresenter">
        <Setter Property="DockPanel.Dock" Value="Top"/>
      </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <TextBlock Background="Lavender" Margin="1" Padding="5" Text="{Binding}"/>
      </DataTemplate>
    </ItemsControl.ItemTemplate>
    <sys:String>Athos</sys:String>
    <sys:String>Porthos</sys:String>
    <sys:String>Aramis</sys:String>
    <sys:String>D'Artagnan</sys:String>
  </ItemsControl>
</Page>
于 2010-10-04T19:32:23.003 回答
3

发生的事情是您的 DockPanel 充满了 ItemsControl。到目前为止,一切都很好。但是,ItemsControl 在内部使用不能垂直填充的 StackPanel(如果设置为 Orientation="Horizo​​ntal",则水平填充。

编辑:为了解释背景是蓝色的...... ItemsControl 的背景默认设置为空。

你知道收藏品有多少吗?

EDIT2:当它是动态集合时,您需要做的是添加以下内容:

<ItemsControl ...>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="1"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <!-- rest of ItemsControl properties -->
</ItemsControl>

Uniform Grid 为每个单元格在水平和垂直方向上分配相等的空间,并且 ItemsPanel 交换标准 StackPanel 以进行定位。

EDIT3:使用高度不等的项目......自定义面板:

public class CustomPanel : StackPanel
{
    protected override Size ArrangeOverride(Size finalSize)
    {
        var childUIElements = Children.OfType<UIElement>().ToList();
        foreach (var child in childUIElements)
        {
            child.Measure(finalSize);
        }
        double remainingHeight = finalSize.Height - childUIElements.Sum(c => c.DesiredSize.Height);
        if(remainingHeight <= 0)
            return base.ArrangeOverride(finalSize);

        double yOffset = 0;
        foreach (var child in childUIElements)
        {
            double height = child.DesiredSize.Height + remainingHeight/childUIElements.Count;
            child.Arrange(new Rect(0,yOffset,finalSize.Width,height));
            yOffset += height;
        }
        return finalSize;
    }
}

如果我没有做太多的 f..-ups 至少应该做一个粗略的版本。如果项目太大而无法容纳,它就像一个普通的堆栈面板一样工作 - 如果不是,它会安排孩子们在他们之间平均分配剩余的空间。如果需要,您可以调整它以按比例分配它(即,较大的块获得更多的剩余空间)。

最后编辑(我认为:-))您需要将此自定义面板放在 ItemsPanelTemplate 中,而不是我之前建议的 UniformGrid 中。

于 2010-10-04T17:43:03.813 回答
0

您是否将 DockPanel.Dock 属性设置为您想要的值?

于 2010-10-04T17:41:41.900 回答
0

我会抛出一个不雅的解决方案:

在模型视图中,将列表绑定切割成一个列表,其中包含除最后一个元素之外的所有元素,然后分别包含最后一个元素。然后使用列表的项目控件,并手动添加一个链接到最后一个元素的额外条目。我讨厌这样做,所以希望有更好的方法。

于 2010-10-04T17:58:25.250 回答