DockPanel ItemsControl 最后一个子项填充

发布于 2024-09-26 12:31:13 字数 775 浏览 6 评论 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 中填充的子项。例如,我过去使用过设置器来指定子项应该停靠在面板的一侧...但似乎没有子项设置器选项来让它展开...

I have a dockpanel that I dynamically fill using an ItemsControl to populate the panel. The dockpanel needs the last child from the itemscontrol list to fill the rest of the panel, but it doesn't seem to happen if I populate it in this fashion... what can I do to get that last item to expand?

snippet of how I have it set up: (note I set the dockpanel background to blue so I could distinguish the populated user controls from the background of the panel)

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

My current hypothesis as to what is happening is the child-fill is being applied to the itemscontrol instead of the children populated within the itemscontrol. I've used setters in the past to specify the child should dock to a side of the panel for instance... but there doesn't seem to be a child setter option to get it to expand...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别靠近我心 2024-10-03 12:31:13

不要将 ItemsControl 放在 DockPanel 中;将DockPanel 放入ItemsControl 中。使用 ItemsPanelTemplate 使 ItemsControl 将其项目放置在 DockPanel 中。

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

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

Don't put the ItemsControl in the DockPanel; put the DockPanel in the ItemsControl. Use the ItemsPanelTemplate to make the ItemsControl lay its items out in a DockPanel.

Use the ItemContainerStyle to set the DockPanel.Dock property on the item containers (which, for an ItemsControl, will be 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>
笑饮青盏花 2024-10-03 12:31:13

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

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

您知道有多少个项目吗? :当它是动态集合

时,您需要做的是添加以下内容:

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

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

EDIT2 高度不等的物品...自定义面板:

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,至少应该做一个粗略的版本,如果物品太大而无法容纳,它的工作方式就像正常的一样。 您可以调整它以按比例分配(即,较大的块获得更多的剩余空间)。

stackpanel - 如果没有,它会安排子项在它们之间平均分配剩余空间。如果需要, :-))您需要将此自定义面板放入 ItemsPanelTemplate 中,而不是我之前建议的 UniformGrid 中。

What is happening is that your DockPanel is filled with the ItemsControl. So far so good. However, the ItemsControl internally uses a StackPanel which cannot fill vertically (horizontally if set to Orientation="Horizontal".

EDIT: To explain the background is blue... the ItemsControl's background is default set to null.

Do you know how many items is in the collection?

EDIT2: What you need to do when it's dynamic collection is add the following:

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

The Uniform Grid assigns an equal amount of space to each cell both horizontally and vertically and the ItemsPanel exchanges the standard StackPanel for positioning.

EDIT3: Working with items of non-equal height... a custom panel:

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

If I haven't made too many f..-ups that should do a crude version at least. If the items are to large to be contained, it works like a normal stackpanel - if not, it arranges the children to split the remaining space evenly between them. You can adjust it to assign it by ratio if you need it (ie. the larger blocks get more of the remaining space).

LAST EDIT (I think :-)) You need to put this custom panel inside the ItemsPanelTemplate instead of the UniformGrid I suggested earlier.

仙女山的月亮 2024-10-03 12:31:13

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

Did you set the DockPanel.Dock property to the value you wanted?

云淡风轻 2024-10-03 12:31:13

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

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

I'll throw out an inelegant solution:

in the modelview, Chop the list binding into a list containing all but the last element, and then the last element separately. Then use the items control for the list, and manually add an extra entry linking to the last element. I'd hate to do this, so hopefully there is a better way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文