1

如果我使用自定义面板来布局我的 ListBoxItems,ListBox 不会尊重它们的组合高度(尽管它确实尊重它们的组合宽度) - 即使我的 ArrangeOverride 返回一个围绕所有项目的大小。

明确设置 ListBox 的高度可以使一切正常,但我希望它自己解决这个问题!

有没有人见过这个?

谢谢

更新:在下面的示例中,ListBox 使用了一个自定义面板,该面板根据 Row 属性垂直堆叠文章,并返回足够大的大小以包围所有文章。但除非我为 ListBox 设置高度,否则它会崩溃!

<UserControl x:Class="SilverlightApplication1.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:SilverlightApplication1">
<UserControl.Resources>
    <DataTemplate x:Key="ArticleTemplate">
        <TextBlock Text="{Binding Title}" />
    </DataTemplate>
</UserControl.Resources>
<ListBox Height="200"
        Background="AntiqueWhite"
        ItemTemplate="{StaticResource ArticleTemplate}"
        ItemsSource="{Binding}" VerticalAlignment="Top"
        Margin="0,0,0,0">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <local:MyPanel />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>
</UserControl>

这是面板:

public class MyPanel : Panel
{
    protected override Size ArrangeOverride(Size arrangeSize)
    {
        double width = 0, height = 0;
        foreach (UIElement child in this.Children)
        {
            var article = (Article)((ContentControl)child).DataContext;
            var y = child.DesiredSize.Height * article.Row;
            var location = new Point(0, y);
            var rect = new Rect(location, child.DesiredSize);
            child.Arrange(rect);
            width = Math.Max(width, child.DesiredSize.Width);
            height = Math.Max(height, y + child.DesiredSize.Height);
        }

        return new Size(width, height);
    }

    protected override Size MeasureOverride(Size availableSize)
    {
        foreach (UIElement child in this.Children)
        {
            if (child != null)
            {
                child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            }
        }

        return new Size();
    }
}

和域类:

public class Article
{
    private readonly int row;
    private readonly string title;

    public Article(string title, int row)
    {
        this.title = title;
        this.row = row;
    }

    public int Row { get { return this.row; } }

    public string Title { get { return this.title; } }
}
4

2 回答 2

1

我无法重现您描述的问题。您能否提供一些示例代码/xaml 以便我看一下?

更新:

我相信这里的问题是您从 MeasureOverride 返回 (0,0) 作为面板的 DesiredSize。您可能想要执行以下操作:

    protected override Size MeasureOverride(Size availableSize)
    {
        double width = 0;
        double height = 0;
        foreach (UIElement child in this.Children)
        {
            if (child != null)
            {
                child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                width = Math.Max(width, child.DesiredSize.Width);
                height = Math.Max(height, child.DesiredSize.Height);
            }
        }

        return new Size(width, height);
    }

根据您的要求,实际的大小调整逻辑可能会有所不同。

您的代码中发生的情况是,通过从 MeasureOverride 返回 (0,0),您的 Panel 本质上是在“询问”其父级为其保留该空间量。因此,当涉及到布局周期的 Arrange 阶段时,传递给 ArrangeOverride 的 finalSize 非常小(至少在一维中为 0)。您可以通过在 ArrangeOverride 中设置断点然后检查 finalSize 参数来验证这一点。为了让您的代码与布局系统一起正常工作,您需要从 MeasureOverride 返回您的 Panel 需要包含其子项的最小空间量。

于 2009-02-08T00:57:51.893 回答
1

不要忘记 ListBoxes 包含 ScrollViewers。ScrollViewer 可能正在查看其子项的高度并认为“很好,我可以处理”,然后设置自己的大小。

尝试设置

ScrollViewer.VerticalScrollBarVisibility = "Hidden"

或者

ScrollViewer.VerticalScrollBarVisibility = "Disabled"

在您的 ListBox 中,看看会发生什么。

于 2009-02-09T02:03:16.673 回答