DockPanel ItemsControl lastchild填充

时间:2010-10-04 17:32:16

标签: c# wpf itemscontrol fill dockpanel

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

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

        <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中填充的子代。我过去曾经使用过setter来指定孩子应该停靠在面板的一侧......例如,似乎没有一个子设置器选项可以让它扩展...

4 个答案:

答案 0 :(得分:6)

请勿将ItemsControl放入DockPanel;将DockPanel放入ItemsControl。使用ItemsPanelTemplateItemsControl的项目放在DockPanel中。

使用ItemContainerStyle在项目容器上设置DockPanel.Dock属性(对于ItemsControl,该属性将为ContentPresenter)。

<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>

答案 1 :(得分:3)

发生的事情是您的DockPanel充满了ItemsControl。到现在为止还挺好。但是,ItemsControl内部使用的StackPanel不能垂直填充(水平设置为Orientation =“Horizo​​ntal”。

编辑:要解释背景为蓝色...... ItemsControl的背景默认设置为null。

你知道馆藏中有多少物品吗?

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;
    }
}

如果我没有制作过多的文件,至少应该做一个粗略的版本。如果要包含的项目很大,它的工作方式就像普通的stackpanel一样 - 如果没有,它会安排孩子们在它们之间平均分割剩余的空间。如果需要,您可以调整它以按比例分配(即,较大的块可以获得更多剩余空间)。

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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