1. 程式人生 > >WPF 基於Adorner實現類似Popup效果

WPF 基於Adorner實現類似Popup效果

1.  什麼是Adorner

     裝飾器是一種特殊型別的FrameworkElement,可用來向用戶提供可視提示。 裝飾器有很多用途,可用來向元素新增功能控制代碼,或者提供有關某個控制元件的狀態資訊。

 

2.  使用Adorner實現Popup的原因

     1. 通過AdornerLayer存在與獨立的佈局系統,不會與介面佈局環論

     2. 使用過WPF中的Popup就可以知道Popup中有許多的限制(例如需要實現某些效果比較麻煩)

 

3. 效果

 

4. 主要實現

    1. Popup中當StaysOpen為False的情況下,當開啟Popup後如果再點選其他區域時將會關閉Popup的實現(實現方法參考自Popup, 但是不採用Mouse.Capture(element),因為會導致其他控制元件無法收到滑鼠實現

複製程式碼
            if (StaysOpen)
                return;

            Point pos = e.GetPosition(ListenMouseElement);
            HitTestResult hitResult = VisualTreeHelper.HitTest(ListenMouseElement, pos);

            if (hitResult == null)
            {
                IsOpen = false;
                return;
            }

            // 如果點選物件對Child則返回
            if (TreeHelper.IsDescendantOf(hitResult.VisualHit, _adorner))
            {
                return;
            }

            // 如果點選物件PlacementTarget則返回
            if (IgnoreTargetEvent && TreeHelper.IsDescendantOf(hitResult.VisualHit, PlacementTarget))
            {
                return;
            }

            IsOpen = false;
複製程式碼

 

    2. 派生Adorner 將AdornerPopup的Child屬性載入到Adorner

複製程式碼
        public FrameworkElementAdorner(FrameworkElement adornerChildElement, FrameworkElement adornedElement,
            AdornerPopup adorner,
            double horizontalOffset
            , double verticalOffset) : base(adornedElement)
        {
            this._child = adornerChildElement;
            this._adorner = adorner;
            this._bgBorder = CreateBackgroundBorder(adornerChildElement);

            this.HorizontalOffset = horizontalOffset;
            this.VerticalOffset = verticalOffset;
        // 通過BaseLogicalChild, AddVisualChild將Child元素載入到可視樹中
            base.AddLogicalChild(_bgBorder);
            base.AddVisualChild(_bgBorder);
        }
複製程式碼

 

程式碼已開源:https://gitee.com/1Jins/WPF-AdornerPopup

 

5. 參考文獻

裝飾器概述    https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/controls/adorners-overview

原文:https://www.cnblogs.com/CLink/p/9896432.html