GetAdornerLayer返回null

时间:2013-04-30 19:23:51

标签: c# wpf

我遇到了问题

AdornerLayer AdornerLayer = AdornerLayer.GetAdornerLayer(布局);

此方法始终返回null。

我做错了什么?

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

        Layout layout = new Layout();
        layout.Background = Brushes.White;
        layout.ClipToBounds = true;
        layout.SnapsToDevicePixels = true;
        layout.Width = 4965; layout.Height = 3515;

        AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(layout);
        adornerLayer.Add(new LayoutAdorner(layout));
    }
}


public class Layout : Canvas
{
    public Visual GetVisualChildAtPoint(Point point)
    {
        return VisualTreeHelper.HitTest(this, point).VisualHit as Visual;
    }
}

public class LayoutAdorner : Adorner
{
    public LayoutAdorner(UIElement adornedElement) : base(adornedElement) { }

    protected override void OnRender(DrawingContext drawingContext)
    {

    }
}

3 个答案:

答案 0 :(得分:7)

在实际加载窗口并创建句柄之前,不会创建窗口的AdornerLayer

您可能需要延迟,而不是将其放置在构造函数中,而是在加载窗口时添加装饰器。

答案 1 :(得分:0)

表单刷新后,调用Content.UpdateLayout();确保内容的所有可视子元素都已正确更新以进行布局。 MSDN Official

(我不太聪明,我只是从这里复制了解决方案): AdornerLayer.GetAdornerLayer() return NULL for all controls in a Panel

答案 2 :(得分:0)

(老问题,但我面临这个问题并且没有找到解决方案) AdornerLayer.GetAdornerLayer在可视化树中搜索AdornerLayer向上。

在构造函数中,不构成可视树。您需要将代码放在Window.Loaded事件中。

其他问题:

Layout layout = new Layout(); ... AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(layout);

搜索向上。但是'布局'是顶级(没有父母)。然后GetAdornerLayer返回null。

要获取Window的AdornerLayer,您需要在Windows中使用合成器(而不是Window,因为Window是最顶层的)。我的解决方案是XAML' root'中的第一个合成者。 :

AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.root);

编辑:

此方法可以从某些类型的WPF元素返回adorner图层:

//If no adorner layer is found, return null
private static AdornerLayer GetAdornerLayer(Visual visual)
{
        var decorator = visual as AdornerDecorator;
        if (decorator != null)
            return decorator.AdornerLayer;
        var presenter = visual as ScrollContentPresenter;
        if (presenter != null)
            return presenter.AdornerLayer;
        var visualContent = (visual as Window)?.Content as Visual;
        return AdornerLayer.GetAdornerLayer(visualContent ?? visual);
}