Using more than 144 adorners

☆樱花仙子☆ 提交于 2019-11-29 07:41:32

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).

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();
        }
    }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!