GetAdornerLayer загадочно возвращает null

Я использовал один и тот же бит кода для нескольких версий моего приложения без проблем, но теперь я загадочно получаю NullRerefenceException со следующим:

this.Loaded += delegate {
    deleteBrush = new DeleteBrushAdorner( background );
    AdornerLayer al = AdornerLayer.GetAdornerLayer( background );
    al.Add( deleteBrush ); // null ref here??
};

background - это просто элемент Border.

Мои две мысли о том, что может быть причиной этого: a) переход на .NET 4.0 и b) размещение экземпляров вышеуказанного элемента (который является UserControl) в ItemsControl.

Странно, что это не происходит все время, и трудно предсказать, когда это произойдет, поэтому оно не является надежным.

Ответ 1

Документы для AdornerLayer.GetAdornerLayer указывают:

Если ни один слой adorner не найден, метод возвращает null.

Итак, я предполагаю, что нет слоев adorner... у вас есть основания полагать, что этого не должно быть? Какую гарантию вы в настоящее время полагаете, что в визуальном дереве будет слой adorner?

Ответ 2

Я знаю, что это старый вопрос, но сегодня у меня была эта проблема.

В моем случае у меня был класс, основанный на Window и GetAdornerLayer(), возвращаемом null. Оказалось, что ControlTemplate для моего производного класса не содержит AdornerDecorator. Добавление этого в качестве верхнего уровня в ControlTemplate решило проблему.

<Style TargetType="my:MyWindow" BasedOn="{StaticResource {x:Type Window}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="my:MyWindow">
                <AdornerDecorator>
                <DockPanel ...>
                </DockPanel>
                </AdornerDecorator>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Ответ 3

Мне любопытно, действительно ли это было решено. AdornerDecorator предоставляет AdornerLayer для элемента под ним - и все будет ниже этого. Это декоратор, то есть у него есть Ребенок, который является контентом. Этот контент предоставляется AdornerLayer. Итак, если вы помещаете AdornerDecorator в свой XAML, а дочерний элемент является границей, граница имеет AdornerLayer.

Кроме того, Window определяет AdornerDecorator как вершину визуального дерева, поэтому любой элемент в Window будет иметь над ним AdornerLayer. Итак, если ваш конус выше был в окне...