弹出式控件Popup
效果图:
点击显示按钮,显示Popup控件
xam代码:
<ctrl:uiPopup x:Name="canvas" Width="150" Grid.Column="1" Placement="Right" Height="{Binding ElementName=window,Path=Height}" VerticalOffset="0" HorizontalOffset="0" IsOpen="False" AllowsTransparency="True" PopupAnimation="Fade"> <Border CornerRadius="0,5,5,0" Background="White" Margin="5"> <Border.Effect> <DropShadowEffect Color="Gray" ShadowDepth="0" BlurRadius="5" Opacity="0.3" Direction="0"/> </Border.Effect> <Grid Background="White"> <Label Content="111111" FontSize="20"/> </Grid> </Border> </ctrl:uiPopup>
重写Popup控件:
public class uiPopup : Popup { /// <summary> /// 是否窗口随动,默认为随动(true) /// </summary> public bool IsPositionUpdate { get { return (bool)GetValue(IsPositionUpdateProperty); } set { SetValue(IsPositionUpdateProperty, value); } } public static readonly DependencyProperty IsPositionUpdateProperty = DependencyProperty.Register("IsPositionUpdate", typeof(bool), typeof(uiPopup), new PropertyMetadata(true, new PropertyChangedCallback(IsPositionUpdateChanged))); private static void IsPositionUpdateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { (d as uiPopup).pup_Loaded(d as uiPopup, null); } /// <summary> /// 加载窗口随动事件 /// </summary> public uiPopup() { this.Loaded += pup_Loaded; } /// <summary> /// 加载窗口随动事件 /// </summary> private void pup_Loaded(object sender, RoutedEventArgs e) { Popup pup = sender as Popup; var win = VisualTreeHelper.GetParent(pup); while (win != null && (win as Window) == null) { win = VisualTreeHelper.GetParent(win); } if ((win as Window) != null) { (win as Window).LocationChanged -= PositionChanged; (win as Window).SizeChanged -= PositionChanged; if (IsPositionUpdate) { (win as Window).LocationChanged += PositionChanged; (win as Window).SizeChanged += PositionChanged; } } } /// <summary> /// 刷新位置 /// </summary> private void PositionChanged(object sender, EventArgs e) { try { var method = typeof(Popup).GetMethod("UpdatePosition", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (this.IsOpen) { method.Invoke(this, null); } } catch { return; } } //是否最前默认为非最前(false) public static DependencyProperty TopmostProperty = Window.TopmostProperty.AddOwner(typeof(Popup), new FrameworkPropertyMetadata(false, OnTopmostChanged)); public bool Topmost { get { return (bool)GetValue(TopmostProperty); } set { SetValue(TopmostProperty, value); } } private static void OnTopmostChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { (obj as uiPopup).UpdateWindow(); } /// <summary> /// 重写拉开方法,置于非最前 /// </summary> /// <param name="e"></param> protected override void OnOpened(EventArgs e) { UpdateWindow(); } /// <summary> /// 刷新Popup层级 /// </summary> private void UpdateWindow() { var hwnd = ((HwndSource)PresentationSource.FromVisual(this.Child)).Handle; RECT rect; if (NativeMethods.GetWindowRect(hwnd, out rect)) { NativeMethods.SetWindowPos(hwnd, Topmost ? -1 : -2, rect.Left, rect.Top, (int)this.Width, (int)this.Height, 0); } } [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } #region P/Invoke imports & definitions public static class NativeMethods { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); [DllImport("user32", EntryPoint = "SetWindowPos")] internal static extern int SetWindowPos(IntPtr hWnd, int hwndInsertAfter, int x, int y, int cx, int cy, int wFlags); } #endregion }
uiPopup来自网络。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?