none
AvalonDock【2.0】 AdornerLayer 显示不了 RRS feed

  • 问题

  • 我正在使用AvalonDock,但是发现一个问题,当floating的时候, AdornerLayer 显示不了

    找到一篇与我情况相同的文档,由于对wpf了解不多,所以也看不太懂,下面贴出添加AdornerLayer的过程,

    希望得到帮助,谢谢

     public class CustomAdorner : Adorner
        {
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="adornedElement">表示和CustomAdorner绑定在一起的对象,及提供绘图表面的元素</param>
            /// <param name="adornerElement">将要显示的内容</param>
            public CustomAdorner(UIElement adornedElement, UIElement adornerElement)
                : base(adornedElement)
            {
                _VisualChildren = new VisualCollection(this);
                _Presenter = new ContentPresenter();
                _Presenter.Content = adornerElement;
                _VisualChildren.Add(_Presenter);
            }
    
            private VisualCollection _VisualChildren;
            private ContentPresenter _Presenter;
    
            protected override Visual GetVisualChild(int index)
            {
                return _VisualChildren[index];
            }
    
            protected override int VisualChildrenCount
            {
                get
                {
                    return _VisualChildren.Count;
                }
            }
    
            protected override Size ArrangeOverride(Size finalSize)
            {
                _Presenter.Arrange(new Rect(finalSize));
                return _Presenter.RenderSize;
            }
        }

    下面是添加AdornerLayer

     /// <summary>
            /// 获取或设置 当前对象的AdornerLayer对象
            /// </summary>
            public AdornerLayer TargetAdornerLayer
            {
                get
                {
                    if (_TargetAdornerLayer == null)
                    {
                        _TargetAdornerLayer = AdornerLayer.GetAdornerLayer(_TargetElement);
                    }
    
                    return _TargetAdornerLayer;
                }
            }
     _LineGeometryRetangle.Rect = new Rect(new Point(curPos.X, curPos.Y - itemActualHeight), new Point(itemRetangleWidth, curPos.Y - itemActualHeight + (itemNode.VisibleControlItem == null ? _StateTreeViewItemHeight : _VisibleItemTreeViewItemHeight)));
                _LineVisualRetangle.Data = _LineGeometryRetangle;
                _HorizontalRetangle = new CustomAdorner(_TargetElement, _LineVisualRetangle);
                TargetAdornerLayer.Add(_HorizontalRetangle);


    与下面文档相同

    http://avalondock.codeplex.com/workitem/15462

    2013年3月21日 9:14

答案

  • 根据你的描述,应该是Floating下的容器没有添加AdornerDecorator,(Window的默认模板中有AdornerDecorator以提供AdornerLayer)。

    参照http://avalondock.codeplex.com/workitem/15462 中的评论,你可以在LayoutFloatingWindowControl.cs的System.Runtime.InteropServices.HandleRef BuildWindowCore(System.Runtime.InteropServices.HandleRef hwndParent) 方法中,把

    rootPresenter = new Border() { Child = Content, Focusable = true };

    改为

    AdornerDecorator adornerDecorator = new AdornerDecorator() { Child = Content };
    _rootPresenter = new Border() { Child = adornerDecorator, Focusable = true };

    从而解决这个问题。


    Min Zhu
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年3月22日 5:47
    版主
  • 添加Adorner的时候仍然使用的是原先的AdornerLayer,所以加不到新窗口上。

    试一下这样

            void Grid_MouseMove(object sender, MouseEventArgs e)
            {
                var grid = sender as Grid;
                if (grid!=null)
                {
                    var adornerLayer = AdornerLayer.GetAdornerLayer(sender as Grid);
                    if (adornerLayer!=null)
                    {
                        Adorner[] adorners = adornerLayer.GetAdorners(grid);
                        if (adorners != null)
                        {
                            //如果存在透明图标则移除
                            if (Array.IndexOf(adorners, _ItemAdorner) != -1)
                                adornerLayer.Remove(_ItemAdorner);
                        }
                        //添加新的Adorner
                        var curPos = e.GetPosition(grid);
                        _SelectionRectGeometry.Rect = new Rect(curPos.X + 5, curPos.Y + 5, 50, 50);
                        _SelectionVisual.Fill = new ImageBrush(_Image);
                        _ItemAdorner = new CustomAdorner(grid, _SelectionVisual);
                        _ItemAdorner.Opacity = 0.8;
                        adornerLayer.Add(_ItemAdorner);
                    }
                }
            }


    Min Zhu
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.



    2013年4月19日 8:13
    版主

全部回复

  • 根据你的描述,应该是Floating下的容器没有添加AdornerDecorator,(Window的默认模板中有AdornerDecorator以提供AdornerLayer)。

    参照http://avalondock.codeplex.com/workitem/15462 中的评论,你可以在LayoutFloatingWindowControl.cs的System.Runtime.InteropServices.HandleRef BuildWindowCore(System.Runtime.InteropServices.HandleRef hwndParent) 方法中,把

    rootPresenter = new Border() { Child = Content, Focusable = true };

    改为

    AdornerDecorator adornerDecorator = new AdornerDecorator() { Child = Content };
    _rootPresenter = new Border() { Child = adornerDecorator, Focusable = true };

    从而解决这个问题。


    Min Zhu
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年3月22日 5:47
    版主
  • 你好,谢谢你的帮助,我试了你的方法,但是当floadting的时候,还是无法显示
    2013年3月22日 16:49
  • 估计你是把先添加的Adorner再转成floating的吧?然后在转换后无法显示?

    这样的话需要你在Content中自行添加AdornerDecorator,不然Adorner不会在转换中保留。


    Min Zhu
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年3月25日 1:38
    版主
  • 你好,我是在floating 之后添加的,依然添加不了,
    2013年4月16日 7:59
  • 能做一个最简化的project,传到SkyDrive上吗?我有空的时候可以帮你看一下


    Min Zhu
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年4月16日 9:49
    版主
  • 先谢,我这就去做
    2013年4月19日 5:57
  • http://sdrv.ms/14ARexs 

    谢谢大婶有空去看看 

    2013年4月19日 7:07
  • 添加Adorner的时候仍然使用的是原先的AdornerLayer,所以加不到新窗口上。

    试一下这样

            void Grid_MouseMove(object sender, MouseEventArgs e)
            {
                var grid = sender as Grid;
                if (grid!=null)
                {
                    var adornerLayer = AdornerLayer.GetAdornerLayer(sender as Grid);
                    if (adornerLayer!=null)
                    {
                        Adorner[] adorners = adornerLayer.GetAdorners(grid);
                        if (adorners != null)
                        {
                            //如果存在透明图标则移除
                            if (Array.IndexOf(adorners, _ItemAdorner) != -1)
                                adornerLayer.Remove(_ItemAdorner);
                        }
                        //添加新的Adorner
                        var curPos = e.GetPosition(grid);
                        _SelectionRectGeometry.Rect = new Rect(curPos.X + 5, curPos.Y + 5, 50, 50);
                        _SelectionVisual.Fill = new ImageBrush(_Image);
                        _ItemAdorner = new CustomAdorner(grid, _SelectionVisual);
                        _ItemAdorner.Opacity = 0.8;
                        adornerLayer.Add(_ItemAdorner);
                    }
                }
            }


    Min Zhu
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.



    2013年4月19日 8:13
    版主
  • 谢谢版主大神啊,问题已经解决了,没想到我的Get方法会有这么大的漏洞。

    但是按逻辑说,我的AdornerLayer是根据它的直接父容器(parent)取的,不管是否是floating,都只是外层发生了变化,和parent和当前的adnorderLayer应该是没有关系的,问题虽然解决了,但是是依然很费解,所以也不太能理解两个AdornerLayer为什么会不一样,难道当floating的时候,从最外层的panel开始,到最底层的控件都是重新添加了新的进去么,所以parent的引用不同了?这感觉就更不何逻辑了,应该不会这么傻去费这么多力

    还是费解,不过谢谢,如能解惑,更是感谢!

    2013年4月19日 15:52
  • 可以Floating的那个控件是一个新的Top Level Window, 不在原先的Visual Tree中。

    其他的部分我也没怎么看过AvalonDock的代码,大致是把原先的控件从父节点移除,加入到了新窗口中吧。


    Min Zhu
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年4月22日 1:35
    版主