Question

It appears that the maximum number of adorners that work without any breakage is 144.

I have a ScrollView with a bunch of objects, and many of them come with adorners. The first 144 adorners are positioned correctly, but the rest are not. Note that it is an exceptional situation when there are so many; usually there are exactly zero adorners. Nevertheless, I'd like this to work properly even on that exceptional occasion.

Leaving aside how this arbitrary (and very low) limit makes me feel, are there any practical work-arounds for this bug?

Was it helpful?

Solution

At this time there is no known way of doing this.

Which is just as well, because I found the performance to be poor; simply subclassing my Image control that was supposed to display the adorner, and drawing the overlay in the OnRender, worked much better (and unlike WinForms, the visual can extend beyond the logical boundary of the control).

OTHER TIPS

Here is the scenario under which I managed to implement a workout for this problem:

I have a number of textboxes that are linked to an Excel document. The textboxes take a numerical value. They are set to invalidate on data errors in the xaml code. A data error occurs if the number is < 1, or null. I placed an AdornerDecorator around the textbox (so that the red invalidation border appears correctly over the textbox). In Excel, you can alter all the textboxes at the same time - but, as the OP found, if you manage to invalidate over 144 text boxes at once, the adorner decorator starts playing up, offsetting the position of the borders (the very thing it was designed to fix in the first place).

I tried a number of different solutions including invalidating the layout, however none of these worked for the situation I was facing. Using Snoop, I found that if I refresh the textbox manually, the adorner then placed itself correctly. So, I decided to call an update to the layout from each individual textbox that needed the adorner. I did this by listening for OnValueUpdated on the textboxes. If the new value it was updating to happened to be an invalid value, I force an "UpdateLayout()" for the textbox (I only wanted to do this for invalid values as forcing an update impacts performance, and I don't want to do that every time the value changes).

In this way, regardless of the number of cells I wanted to change at once, the adorner decorator was always displayed in the correct position (except for the very last textbox to be evaluated which, despite my best efforts, is always ever so slightly misaligned).

This might be way late to the party here, but this seemed to solve the problem for me. I kept a list of the adorners that I had added to the adorner layer (called m_adorners), and in the root control where my adorners were contained, I attach to the LayoutUpdated event. Here's event handler:

    private void OnLayoutUpdated(object sender, EventArgs e)
    {
        if (m_adorners.Any(a => !a.IsArrangeValid && 
               a.Parent != null))
        {
            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
            adornerLayer.InvalidateArrange();
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top