Why doesn't ListBoxItem call MeasureOverride when its width changes?

Thus, for purposes of illustration below, I created a subclass ListBoxItemand a subclass ListBox, which uses it as a container by redefining how IsItemItsOwnContainerOverrideand GetContainerForItemOverride.

Now, when the window first appears, it is expected to be MeasureOverridecalled on each ListBoxItem(with Infinity, Infinity), followed by ArrangeOverridewhich is called for each element.

However, when you resize ListBoxto ListBoxItem, it MeasureOverrideis not called only ArrangeOverride, although the metadata for the width property is set to AffectsMeasure.

NotE: I know that I can get around this by setting it ScrollViewer.HorizontalScrollbarVisibilityto “Disabled”, and in this case MeasureOverridereceives the call as expected, because this scroll option causes the items to fit the width of the list and therefore naturally re-fire. However, I'm still trying to understand why Measure is still not called by default, because the metadata for the property Widthhas a flag AffectsMeasure, and the width is changed with a step ArrangeOverride.

Is this flag only a hint for its container, and in the case of a control placed in ScrollViewer, is it ignored? I assume that unless you turn off scrolling, the controls have an infinite area available to them, so once they are measured, there is no need to re-measure them again. However, turn off horizontal scrolling and you indicate that the width is not unlimited, so it is called again MeasureOverride. But this is just an assumption, albeit a logical one.

Here is a sample code to play. Create a new WPF project and paste it into the CodeBehind window and look at the debug output. Then set the HorizontalScrollbarVisibility flag and you will see that it is called.

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

}
+1
1

, , - - , , , , .

ScrollViewer.HorizontalScrollbarVisibility Disabled ListBox, , , , .

0

All Articles