Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I reset the DesiredSize on a UIElement

I have a list box that contains any number of UIElements whose size are unknown.

I want to be able to track the proposed size of the list box after each item has been added. This will allow me to split a large list (ex: 100 items) into several (ex: 10) smaller lists of roughly the same visual size, regardless of the visual size of each element in the list.

However, it appears that a Measure pass only affects the ListBox's DesiredSize property on the first call to Measure:

public partial class TestWindow : Window
{
    public TestWindow()
    {
        InitializeComponent();

        ListBox listBox = new ListBox();
        this.Content = listBox;

        // Add the first item
        listBox.Items.Add("a"); // Add an item (this may be a UIElement of random height)
        listBox.Measure(new Size(double.MaxValue, double.MaxValue)); // Measure the list box after the item has been added
        Size size1 = listBox.DesiredSize; // reference to the size the ListBox "wants"

        // Add the second item
        listBox.Items.Add("b"); // Add an item (this may be a UIElement of random height)
        listBox.Measure(new Size(double.MaxValue, double.MaxValue)); // Measure the list box after the item has been added
        Size size2 = listBox.DesiredSize; // reference to the size the ListBox "wants"

        // The two heights should have roughly a 1:2 ratio (width should be about the same)
        if (size1.Width == size2.Width && size1.Height == size2.Height)
            throw new ApplicationException("DesiredSize not updated");
    }
}

I have tried adding a call to:

listBox.InvalidateMeasure();

in between adding items to no avail.

Is there an easy way to calculate the desired size of a ListBox (or any ItemsControl) at the time items are being added?

like image 524
Michael Avatar asked Oct 11 '22 00:10

Michael


1 Answers

There are some optimizations in the measuring phase that would "reuse" the previous measurements if the same size is passed to the Measure method.

You can try using different values to ensure that the measurement is truly recalculated, like so:

// Add the second item
listBox.Items.Add("b"); // Add an item (this may be a UIElement of random height)
listBox.Measure(new Size(1, 1));
listBox.Measure(new Size(double.MaxValue, double.MaxValue));
like image 168
CodeNaked Avatar answered Oct 14 '22 04:10

CodeNaked