自定义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
}
}
自定义WPF Popup控件的更多相关文章
- WPF Popup 控件导致被遮挡内容不刷新的原因
WPF Popup 控件导致被遮挡内容不刷新的原因 周银辉 今天在写一个WPF控件时用到了Popup控件,很郁闷的情况是:当popup关闭时,原来被popup挡住的界面部分不刷新,非要手动刷新一下(比 ...
- 示例:自定义WPF底层控件UI库 HeBianGu.General.WpfControlLib V2.0版本
原文:示例:自定义WPF底层控件UI库 HeBianGu.General.WpfControlLib V2.0版本 一.目的:封装了一些控件到自定义的控件库中,方便快速开发 二.实现功能: 基本实现常 ...
- 自定义WPF分页控件
一.分页控件功能说明 实现如上图所示的分页控件,需要实现一下几个功能: 可以设置每页能够展示的最大列数(例如每页8列.每页16列等等). 加载的数组总数量超过设置的每页列数后,需分页展示. 可以直接点 ...
- WPF popup控件的使用
<Window x:Class="WPFPopup.RuntimePopup" xmlns="http://schemas.microsoft.com/wi ...
- 解决wpf popup控件遮挡其他程序的问题
public class PopupNonTopmost : Popup { public static DependencyProperty TopmostProperty = Window.Top ...
- WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 下拉选 ...
- 【转】WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要内容: 下拉选择控件ComboBox的自定义样式及扩展: 自定义多选控件Mul ...
- WPF 自定义ComboBox样式,自定义多选控件
原文:WPF 自定义ComboBox样式,自定义多选控件 一.ComboBox基本样式 ComboBox有两种状态,可编辑和不可编辑状态.通过设置IsEditable属性可以切换控件状态. 先看基本样 ...
- WPF自定义选择年月控件详解
本文实例为大家分享了WPF自定义选择年月控件的具体代码,供大家参考,具体内容如下 封装了一个选择年月的控件,XAML代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
随机推荐
- c++ c的拓展
C++对c的拓展之, 引用和const关键字 bool类型关键字 C++中的布尔类型 C++在C语言的基本类型系统之上增加了bool C++中的bool可取的值只有true和false 理论上bool ...
- JDK8 Steam流操作
原文:https://github.com/niumoo/jdk-feature/blob/master/src/main/java/net/codingme/feature/jdk8/Jdk8Str ...
- 云数据库 Redis 版,知识点
资料 网址 什么是云数据库Redis版 https://help.aliyun.com/document_detail/26342.html?spm=a2c4g.11174283.6.542.6b11 ...
- 16-cmake语法-OpeCV3.3.1_CMakeLists.txt的部分注释
OpeCV3.3.1 的 CMakeLists.txt 的部分注释. # Disable in-source builds to prevent source tree corruption. # @ ...
- [Algorithm] 202. Happy Number
Write an algorithm to determine if a number is "happy". A happy number is a number defined ...
- ubunt 文件permission denied问题的解决
在linux系统使用过程中,升级python到3.6以后,执行pip命令,遇到permission denied问题,系统显示如下: -bash: /home/www/my_flask/venv/bi ...
- php+ajax无刷新分页原生ajax实现分页最简单完整实例-完整代码,
展示页面:index.html <html><script> function ajax_show() { // 获取当前页 var page =1; var xhr = ne ...
- docker的简单操作和端口映射
一:简介 Docker镜像 在Docker中容器是基于镜像启动的 镜像是启动容器的核心 镜像采用分层设计,最顶层为读写层 使用快照COW技术,确保底层不丢失 通过ifconfig(ip a)来查看d ...
- Python实现网络图形化界面多人聊天室 - Linux
网络图形化界面多人聊天室 - Linux Windows版本:https://www.cnblogs.com/noonjuan/p/12078524.html 在Python实现网络多人聊天室基础上, ...
- 【07月02日】A股滚动市盈率PE最低排名
仅根据最新的市盈率计算公式进行排名,无法对未来的业绩做出预测. 方大集团(SZ000055) - 滚动市盈率PE:2.68 - 滚动市净率PB:1.2 - 滚动年化股息收益率:3.78% - 建筑产 ...