zoukankan      html  css  js  c++  java
  • 自定义WPF Popup控件

    解决问题

    1、WPF Popup 不随着 Window 一起移动的问题

    2、WPF Popup 总是显示在最前面

    引用命名空间

     xmlns:ctrl="clr-namespace:Micro.UI.Controls"

    XAML

    <ctrl:uiPopup x:Name="canvas" VerticalOffset="-410" IsOpen="True" AllowsTransparency="True" PopupAnimation="Fade">
    </ctrl:uiPopup>
    

      

    C#

    using System;
    using System.Runtime.InteropServices;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Threading;
    using System.Windows.Interop;
    using System.Windows.Media;
    using System.Windows.Controls.Primitives;
    
    namespace Micro.UI.Controls
    {
        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
        }
    }
    

      

  • 相关阅读:
    Zend Framework 2.1.5 中根据服务器的环境配置调用数据库等的不同配置
    在基于 Eclipse 的 IDE 中安装和使用 Emmet(ZenCoding)
    【翻译】Emmet(Zen Coding)官方文档 之六 自定义 Emmet
    【翻译】Emmet(Zen Coding)官方文档 之二 缩写
    【翻译】Emmet(Zen Coding)官方文档 之七 一览表
    【翻译】Emmet(Zen Coding)官方文档 之三 CSS 缩写
    【翻译】Emmet(Zen Coding)官方文档 之四 动作
    【翻译】Emmet(Zen Coding)官方文档 之一 web 编程的必备工具
    Zend Framework 2 时区设置警告问题的解决
    【翻译】Emmet (Zen Coding) 元素类型
  • 原文地址:https://www.cnblogs.com/sntetwt/p/11345072.html
Copyright © 2011-2022 走看看