GetAdornerLayer 返回 null 的神秘原因

12

我一直在使用同样的代码版本来开发我的应用,并且没有遇到任何问题,但是现在却神秘地收到以下的NullReferenceException异常:

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中。

奇怪的是,这种情况并不总是发生,而且很难预测何时会发生,因此它并不可靠。

4个回答

14

在我的情况下,我有一个基于 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>

8

AdornerLayer.GetAdornerLayer的文档说明:

如果未找到adorner层,则该方法返回null。

因此我的猜测是没有adorner层......您有什么理由认为这不是这种情况吗?您当前依赖于哪种保证有一个adorner层在视觉树中?


2
如果我使用 AdornerDecorator 而不是 Border,则会发生同样的事情,尽管我现在根据 MSDN 的说法看到它“为视觉树中下方的元素提供了装饰层”。让我尝试将 Border 包装在 AdornerLayer 中... - devios1
在我的情况下,它是null,因为我尝试过早地访问它(构造函数或OnPropertyChanged)。我能够在OnRender()中访问它,但当然AdornerDecorator也必须在控件模板中。 - Michael Brown

4
我很好奇这个问题是否真的被解决了。AdornerDecorator为其下方的元素提供AdornerLayer,而且所有内容都会在其下方。它是一个装饰器,意味着它有一个作为内容的Child。该内容被提供了一个AdornerLayer。因此,如果您在XAML中放置一个AdornerDecorator,并将Child设置为边框,则边框确实具有AdornerLayer。
此外,Window将AdornerDecorator定义为可视树的顶部,因此窗口中的任何元素都会在其上方具有AdornerLayer。所以,如果您的内容在一个Window中...

2
最终解决方案是在可视树中将AdornerDecorator放置在Border上方(即作为其父级)。虽然这确实是在一个无边框窗口中,但也许这是.NET 4的一个问题,因为在.NET 3.5中没有AdornerDecorator也可以正常工作。 - devios1
我遇到了同样的问题。我试图装饰窗口内部的控件,但是无论我尝试获取adorner层的方式是什么,GetAdornerLayer都返回null。 - kubal5003

0
这个回答可能有点晚,但无论如何...
AdornerDecorators文档中写道:
“如果您传递的元素在其可视树中没有AdornerDecorator作为祖先,则GetAdornerLayer方法返回null。”
所以也许你的background元素不是AdornerDecorator的子元素?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接