Popup 解决StayOpen=true时,置顶的问题

/// <summary>
/// 解决StayOpen=true时,永远置顶问题的Popup控件
/// </summary>
public class EasiNotePopup : Popup
{
public static readonly DependencyProperty IsTopmostProperty = DependencyProperty.Register("IsTopmost", typeof(bool), typeof(EasiNotePopup), new FrameworkPropertyMetadata(false, OnIsTopmostChanged));

private bool? _appliedTopMost;
private bool _alreadyLoaded;
private Window _parentWindow;

public bool IsTopmost
{
get { return (bool)GetValue(IsTopmostProperty); }
set { SetValue(IsTopmostProperty, value); }
}

/// <summary>
/// ctor
/// </summary>
public EasiNotePopup()
{
Loaded += OnPopupLoaded;
Unloaded += OnPopupUnloaded;
}

void OnPopupLoaded(object sender, RoutedEventArgs e)
{
if (_alreadyLoaded)
return;

_alreadyLoaded = true;

if (Child != null)
{
Child.AddHandler(PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(OnChildPreviewMouseLeftButtonDown), true);
}

_parentWindow = Window.GetWindow(this);

if (_parentWindow == null)
return;

_parentWindow.Activated += OnParentWindowActivated;
_parentWindow.Deactivated += OnParentWindowDeactivated;
}

private void OnPopupUnloaded(object sender, RoutedEventArgs e)
{
if (_parentWindow == null)
return;
_parentWindow.Activated -= OnParentWindowActivated;
_parentWindow.Deactivated -= OnParentWindowDeactivated;
}

void OnParentWindowActivated(object sender, EventArgs e)
{
SetTopmostState(true);
}

void OnParentWindowDeactivated(object sender, EventArgs e)
{
Debug.WriteLine("Parent Window Deactivated");

if (IsTopmost == false)
{
SetTopmostState(IsTopmost);
}
}

void OnChildPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{

SetTopmostState(true);

if (!_parentWindow.IsActive && IsTopmost == false)
{
_parentWindow.Activate();
}
}

private static void OnIsTopmostChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var thisobj = (EasiNotePopup)obj;

thisobj.SetTopmostState(thisobj.IsTopmost);
}

protected override void OnOpened(EventArgs e)
{
SetTopmostState(IsTopmost);
base.OnOpened(e);
}

private void SetTopmostState(bool isTop)
{
if (_appliedTopMost.HasValue && _appliedTopMost == isTop)
{
return;
}

if (Child == null)
return;

var hwndSource = (PresentationSource.FromVisual(Child)) as HwndSource;

if (hwndSource == null)
return;
var hwnd = hwndSource.Handle;

RECT rect;

if (!GetWindowRect(hwnd, out rect))
return;

if (isTop)
{
SetWindowPos(hwnd, HWND_TOPMOST, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
}
else
{
// 重新激活Topmost,需要bottom->top->notop
SetWindowPos(hwnd, HWND_BOTTOM, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
SetWindowPos(hwnd, HWND_TOP, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
SetWindowPos(hwnd, HWND_NOTOPMOST, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
}

_appliedTopMost = isTop;
}

[StructLayout(LayoutKind.Sequential)]
public struct RECT

{
public int Left;
public int Top;
public int Right;
public int Bottom;
}

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

[DllImport("user32.dll")]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
int Y, int cx, int cy, uint uFlags);

static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
static readonly IntPtr HWND_TOP = new IntPtr(0);
static readonly IntPtr HWND_BOTTOM = new IntPtr(1);

private const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 SWP_NOZORDER = 0x0004;
const UInt32 SWP_NOREDRAW = 0x0008;
const UInt32 SWP_NOACTIVATE = 0x0010;

const UInt32 SWP_FRAMECHANGED = 0x0020; /* The frame changed: send WM_NCCALCSIZE */
const UInt32 SWP_SHOWWINDOW = 0x0040;
const UInt32 SWP_HIDEWINDOW = 0x0080;
const UInt32 SWP_NOCOPYBITS = 0x0100;
const UInt32 SWP_NOOWNERZORDER = 0x0200; /* Don’t do owner Z ordering */
const UInt32 SWP_NOSENDCHANGING = 0x0400; /* Don’t send WM_WINDOWPOSCHANGING */

//很重要,窗口切换等需要将popup显示层级重新刷新
const UInt32 TOPMOST_FLAGS =
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSENDCHANGING;
}

时间: 2024-10-29 18:31:09

Popup 解决StayOpen=true时,置顶的问题的相关文章

scroll中放入listview,并解决scroll初始化不置顶问题

首先,scroll中放入listview的话,listview是显示不全的,这时候需要动态修改listview的长度 public void setListViewHeight(ListView listView) { // 获取ListView对应的Adapter ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { return; } int totalHeight = 0; for (int

解决点击锚点置顶内容被导航遮住

工作中我第一次遇到这种情况,因为是接手公司的老项目,在原来项目的基础上修改,而且这项目里的相应文件都非常乱,结构.样式.行为都不分离的,处理起来有点棘手,看着代码脑袋都疼:由于点击锚点,内容会默认置顶,被导航栏遮住.一开始我都在网上找解决的方案,但是后来,我还是选择了一个比较笨的办法,就是将锚点所在的元素独立出来如下: <a name="anchor" style="display:block;height:44px;margin-top:-44px;">

百度编辑器在服务器置顶路径 解决上传图片创建目录失败的方法(Thinkphp)

1.设置文件夹权限 2.修改 /* 前后端通信相关的配置,注释只允许使用多行方式 */ { /* 上传图片配置项 */ "imageActionName": "uploadimage", /* 执行上传图片的action名称 */ "imageFieldName": "upfile", /* 提交的图片表单名称 */ "imageMaxSize": 2048000, /* 上传大小限制,单位B */ &qu

WPF实现只打开一个窗口,并且重复打开时已经打开的窗口置顶

内容来自:https://codereview.stackexchange.com/questions/20871/single-instance-wpf-application 第一步:添加System.RunTime.Remoting引用 第二步:新建一个类class1.cs(按自己想法命名) using System; using System.Collections; using System.Collections.Generic; using System.ComponentMode

[置顶]基于MVC4+EasyUI的Web开发框架经验总结(6)在页面中应用下拉列表的处理(转载)

[置顶]基于MVC4+EasyUI的Web开发框架经验总结(6)在页面中应用下拉列表的处理 在很多Web界面中,我们都可以看到很多下拉列表的元素,有些是固定的,有些是动态的:有些是字典内容,有些是其他表里面的名称字段:有时候引用的是外键ID,有时候引用的是名称文本内容:正确快速使用下拉列表的处理,可以提高我们程序界面的美观性和友好型,本文主要介绍在我的Web开发框架以及相关的扩展Web应用中用到的一些代表性下拉列表的处理场景,希望给大家做个参考学习. 1.固定下拉列表的处理 代表性的固定列表有人

在UWP中页面滑动导航栏置顶

最近在研究掌上英雄联盟,主要是用来给自己看新闻,顺便copy个界面改一下段位装装逼,可是在我copy的时候发现这个东西 当你滑动到一定距离的时候导航栏会置顶不动,这个特性在微博和淘宝都有,我看了@ms-uap的文章,淘宝的实现方式是改变顶部显示栏的大小,我本来准备按照他那个思路去做的,但发现效果不理想,在滑动的时候,底部的界面也跟着在滑动,这样使得很不友好,所以我准备自己实现一个 先上个最终效果图吧,图比较大,请耐心等待 思路大概是这样的 将这个界面分为两行 <Grid.RowDefinitio

[置顶] Android开发笔记(成长轨迹)

分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API 调用了未实现的OpenGL ES API函数,一般由于导入的第三方库如地图库,里面有用到OpenGL,但是模拟器的硬件默认是没有这个的,所以需要我们编辑模拟器Emulation Options选项勾选 Use Host GPU 然后重启模拟器再尝试,如果还是这个错误,那么我们只好用真机测试了. 2.

Mysql数据库实现的简单置顶

Mysql数据库实现的简单置顶 1. 问题背景:小编要做一个文章管理的简单网页,用的是Mysql数据库.其中需要文章置顶功能,如图: 2. 最初的思路:机智的小编立刻大脑飞速运转,很快想到为存储文章的"article"表设定一个(int)型的"isTop"属性,0表示不置顶,大于0表示置顶且数字越大,优先级越高.显示的时候只需按照"isTop"降序显示.当用户需要将"id"为"001"的文章置顶时,后台只需

iOS使用UIPageViewController结合多个UITableView后点击状态栏无法让UITableView置顶问题

页面结构:1个UIPageViewController含多个其他ViewController,每个ViewController中又包含了一个UITableView 问题:无法通过点击状态栏,让当前UITableView内容置顶 原因:UIPageViewController帮助我们管理了多个ViewController,本质上在UIPageViewController的view中包含多多个ViewController中的UITableView.由于每个UITableView的scrollsToT