WPF 基於Adorner實現類似Popup效果
阿新 • • 發佈:2018-11-02
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