1

好的,为了说明的目的,下面我创建了一个 的子类ListBoxItem和 的一个子类,它通过覆盖和ListBox来使用它作为它的容器。IsItemItsOwnContainerOverrideGetContainerForItemOverride

现在,当窗口首次出现时,正如预期的那样,MeasureOverride在每个ListBoxItem(使用 Infinity,Infinity)ArrangeOverride上调用,然后在每个项目上调用。

但是,当调整ListBox, only的大小时,不会ArrangeOverride调用,即使 width 属性的元数据设置为。ListBoxItemMeasureOverrideAffectsMeasure

注意:我知道我可以通过设置ScrollViewer.HorizontalScrollbarVisibility为“禁用”来解决这个问题,在这种情况下MeasureOverride会按预期调用,因为滚动设置会强制项目与列表框的宽度匹配,因此自然会重新触发。但是,我仍在试图弄清楚为什么默认情况下不调用 Measure,因为Width属性的元数据AffectsMeasure设置了标志,并且宽度正在通过ArrangeOverride步骤发生变化。

该标志是否只是对其容器的提示,并且对于放置在其中的控件,ScrollViewer它会被忽略吗?我的猜测是,除非您禁用滚动,否则控件有无限的可用区域,因此一旦测量它们,就无需再次重新测量它们。但是禁用水平滚动并且您说宽度不是无限的,因此MeasureOverride再次调用。但这只是一个猜测,尽管是合乎逻辑的。

这是可以使用的示例代码。创建一个新的 WPF 项目并将其粘贴到窗口的 CodeBehind 中并查看调试输出。接下来,设置 Horizo​​ntalScrollbarVisibility 标志,您会看到它确实被调用了。

public partial class MainWindow : Window
{
    public MainWindow(){
        InitializeComponent();
        var items = new List<object>(){ "This is a really, really, really, really long sentence"};
        var lbx = new ListBoxEx { ItemsSource = items };
        this.Content = lbx;
    }

}

public class ListBoxEx : ListBox
{
    protected override bool IsItemItsOwnContainerOverride(object item){
        return (item is ListBoxItemEx);
    }

    protected override DependencyObject GetContainerForItemOverride(){
        return new ListBoxItemEx();
    }
}

public class ListBoxItemEx : ListBoxItem
{
    protected override Size MeasureOverride(Size availableSize){
        Console.WriteLine("MeasureOverride called with " + availableSize);
        return base.MeasureOverride(availableSize);
    }

    protected override Size ArrangeOverride(Size finalSize){
        Console.WriteLine("ArrangeOverride called with " + finalSize);
        return base.ArrangeOverride(finalSize);
    }

}
4

1 回答 1

0

好的,我认为答案是它没有触发,因为 Measure pass 正在影响面板,而不是项目,并且面板本身没有调整大小,因此没有理由重新测量其子项。

但是,当设置ScrollViewer.HorizontalScrollbarVisibility为时Disabled,面板的宽度会跟踪 ListBox 的宽度,而不是其内容,因此确实需要重新测量子项,这就是他们在这种情况下的原因。

于 2015-12-14T17:50:10.260 回答