问题一.popup总是置顶,遮挡其他窗口

最近发现popup设置打开后,总是会遮挡其他窗口,而我们只想让它仅仅在应用程序的上一层即可,并不像让它在最上面

解决方案是继承Popup重新定义控件PopupEx。

public class PopupEx : Popup
{
public static DependencyProperty TopmostProperty = Window.TopmostProperty.AddOwner(typeof(PopupEx ), 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 PopupEx ).UpdateWindow();
}
protected override void OnOpened(EventArgs e)
{
UpdateWindow();
}
private void UpdateWindow()
{
var hwnd = ((HwndSource)PresentationSource.FromVisual(this).Handle;
RECT rect;
if (GetWindowRect(hwnd, out rect))
{
SetWindowPos(hwnd, Topmost ? -1 : -2, rect.Left, rect.Top, (int)this.Width, (int)this.Height, 0);
}
}
#region imports definitions
[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", EntryPoint = "SetWindowPos")]
private static extern int SetWindowPos(IntPtr hWnd, int hwndInsertAfter, int x, int y, int cx, int cy, int wFlags);
#endregion
}

然后在调用该控件的时候设置该PopupEx的属性 Topmost=False即可。

以上方法来自 Leaco 的博客:http://www.cnblogs.com/Leaco

但是,呵呵,然并软,在new该popupEx的时侯设置topmost=false之后,还是会置顶

后来再加上了一句代码即可解决这个问题:就是在将popupEx加入到某个panel或者父容器当中,因为popup的parent的只读的,无法赋值,

所以我就让一个dockpanel.Children.Add(popupEx),配合PopupEx类,就完美解决了该问题。

************2016.11.16******************************

问题二.popup无法跟随主窗体移动或者更新状态

后来发现这个popup随着窗体移动不会消失,网上流传的方法就是在主窗体的locationchanged事件和sizechanged事件里面

回调一个函数,代码如下:

Loaded += (sender, e) =>

              {

                  Window window = Window.GetWindow(this);

                  window.LocationChanged += HandleMovePopup;

                  window.SizeChanged += HandleMovePopup;

              };

void HandleMovePopup(object sender, EventArgs e)

        {

            if (NewMsgPop != null && NewMsgPop.IsOpen)

            {

                var mi = typeof(Popup).GetMethod("UpdatePosition", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

                mi.Invoke(NewMsgPop, null);

            }

        }

是可以解决这个移动窗体的问题。然并软,还有更坑爹的事情,当程序不在最顶部,既有其他应用程序在最顶部时,

此时再让popup.isopen=true时,还是会显示在其他应用程序之前。。。。。。。。。。

真是欲哭无泪,最后的解决方案是:改成一个label, 通过设置Gird.SetZindex(label,0)或者Gird.SetZindex(label,2)来控制label的显隐。

前提是将label放进一个Grid里面

至此,这个功能需求算是圆满完成了,留给我的启发是,以后能不用popup尽量不用。。。。。。。

当然肯定有办法能解决这个问题,迫于项目压力,没有时间去细究,

当然如果有高人能说出更厉害的方法来解决这个问题,希望能赐教!

************2016.11.24******************************

问题三:Popup如何拖动

有几个思路,第一,是得到鼠标位置,然后通过API发消息给popup通知其修改自己的位置,第二是在mousemove事件里直接修改popup的位置。

第一种方法可参考该博客:http://www.cnblogs.com/lisweden/p/3183476.html

然后介绍第二种方法:

要引用 system.windows.itneractivity.dll

然后新建class

  public class popup_dragmove_behavior : Behavior<Popup>
{
public bool _mouse_down;
Point _old_pos; Point _orignal_pos;
double max_vertical_offset;
public popup_dragmove_behavior()
{ }
protected override void OnAttached()
{
base.OnAttached(); AssociatedObject.MouseLeftButtonDown += (sender, e) =>
{
mouse_left_button_down(sender, e);
};
AssociatedObject.MouseLeftButtonUp += (sender, e) =>
{
mouse_left_button_up(sender, e);
};
AssociatedObject.MouseMove += (sender, e) =>
{
mouse_move(sender, e);
};
AssociatedObject.Closed += (sender, e) =>
{
popup_close(sender, e);
};
} protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.MouseLeftButtonDown -= (sender, e) =>
{
mouse_left_button_down(sender, e);
};
AssociatedObject.MouseLeftButtonUp -= (sender, e) =>
{
mouse_left_button_up(sender, e);
};
AssociatedObject.MouseMove -= (sender, e) =>
{
mouse_move(sender, e);
};
AssociatedObject.Closed -= (sender, e) =>
{
popup_close(sender, e);
};
} void mouse_left_button_down(Object sender, MouseButtonEventArgs e)
{
_mouse_down = true;
if (AssociatedObject.VerticalOffset == 0)
{
_orignal_pos = AssociatedObject.Child.PointToScreen(new Point(AssociatedObject.ActualWidth, 0));
max_vertical_offset = 0 - _orignal_pos.Y;
}
_old_pos = AssociatedObject.Child.PointToScreen(e.GetPosition(AssociatedObject.Child));
AssociatedObject.Child.CaptureMouse();
} void mouse_move(Object sender, MouseEventArgs e)
{
if (!_mouse_down)
{
return;
}
var child_pos = e.GetPosition(AssociatedObject.Child);
var new_pos = AssociatedObject.Child.PointToScreen(child_pos);
var offset = new_pos - _old_pos;
_old_pos = new_pos;
AssociatedObject.HorizontalOffset += offset.X;
var new_VerticalOffset = AssociatedObject.VerticalOffset + offset.Y;
if (new_VerticalOffset < max_vertical_offset)
{
new_VerticalOffset = max_vertical_offset;
}
AssociatedObject.VerticalOffset = new_VerticalOffset;
} void mouse_left_button_up(Object sender, MouseButtonEventArgs e)
{
_mouse_down = false;
AssociatedObject.Child.ReleaseMouseCapture();
} void popup_close(Object sender, EventArgs e)
{
AssociatedObject.HorizontalOffset = 0;
AssociatedObject.VerticalOffset = 0;
}
}

然后这样调用即可:

popup_dragmove_behavior  be=new popup_dragmove_behavior();

be.Attch(your_popup);

但是这个方法有个缺点是,无法将popup拖出屏幕之外

总结:除非真的非popup不可,那么一般情况下,直接用window会省事很多。。。。。。

WPF Popup实现拖动的更多相关文章

  1. WPF Popup 控件导致被遮挡内容不刷新的原因

    WPF Popup 控件导致被遮挡内容不刷新的原因 周银辉 今天在写一个WPF控件时用到了Popup控件,很郁闷的情况是:当popup关闭时,原来被popup挡住的界面部分不刷新,非要手动刷新一下(比 ...

  2. WPF Popup 置顶问题

    原文 WPF Popup 置顶问题 问题: 使用wpf的popup,当在popup中弹出MessageBox或者打开对话框的时候,popup总是置顶,并遮住MessageBox或对话框. 解决: 写如 ...

  3. WPF Popup全屏 弹出方法。解决只显示75%的问题。

    WPF Popup全屏 弹出方法.解决只显示75%的问题.   WPF 中 Popup 有一个特点.当Popup的高度超过屏幕的75%的时候,只显示75%的高度. 如下代码: <Window x ...

  4. [转载]WPF控件拖动

    这篇博文总结下WPF中的拖动,文章内容主要包括: 1.拖动窗口 2.拖动控件 Using Visual Studio 2.1thumb控件 2.2Drag.Drop(不连续,没有中间动画) 2.3拖动 ...

  5. WPF 使用鼠标拖动一个控件的实现[2018.7.15]

    原文:WPF 使用鼠标拖动一个控件的实现[2018.7.15] Q:已经把一个Shape和一个TextBlock组合起来放到了一个Grid中,现在想要实现用鼠标拖动这个Grid到任意位置的功能,如何做 ...

  6. WPF无边框拖动、全屏、缩放

    原文:WPF无边框拖动.全屏.缩放 版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/lwwl12/article/details/78059361 先看效果 ...

  7. 自定义WPF Popup控件

    解决问题 1.WPF Popup 不随着 Window 一起移动的问题 2.WPF Popup 总是显示在最前面 引用命名空间 xmlns:ctrl="clr-namespace:Micro ...

  8. wpf Popup Win8.0 bug HorizontalOffset 弹出位置偏移

    问题描述参考 wpf 客户端[JDAgent桌面助手]开发详解(四) popup控件的win8.0的bug 当开发完程序后,我们在多操作系统测试时候发现:win8.0  系统中 popup 弹出的位置 ...

  9. C# WPF 中WebBrowser拖动来移动窗口,改变窗口位置

    前言 wpf中的WebBrowser相比之前的winform阉割了不少东西,也增加了不少东西,但是msdn对wpf也没有较好的文档 WebBrowser可以说是一个.NET控件,相对于WPF中的控件, ...

随机推荐

  1. nginx使用手册--nginx的命令行参数

    nginx的命令行参数 -? 或者 -h 打印命令行参数帮助信息 -c file 为 Nginx 指定一个配置文件,来代替缺省的. -t 不运行,而仅仅测试配置文件.nginx 将检查配置文件的语法的 ...

  2. NopCommerce3.9安装

    除非另外说明,否则本分类所有博文的NopCommerce都基于3.9版本. 用vs2015打开,其他版本的vs没试过. 首先打开解决方案,然后设置Nop.web为启动项目. 启动项目,项目即可自动编译 ...

  3. mapduce简介

    原文引自:http://www.cnblogs.com/shishanyuan/p/4639519.html 1.环境说明 部署节点操作系统为CentOS,防火墙和SElinux禁用,创建了一个shi ...

  4. Codeforces 500D. New Year Santa Network

    题目大意 给你一颗有\(n\)个点的树\(T\),边上有边权. 规定,\(d(i,j)\)表示点i到点j路径上的边权之和. 给你\(q\)次询问,每次询问格式为\(i, j\),表示将按输入顺序排序的 ...

  5. touch滑动事件---简单小案例

    html: <!--导航栏头部--><div class="type_nav"> <ul class="clearfix " v- ...

  6. SQL server插入数据后,获取自增长字段的值

      ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 insert into Tb_People(uname,er ...

  7. linux学习(三)-----linux用户管理、实用指令

    用户管理 基本介绍 说明: 1.Linux 系统是一个多用户多任务的操作系统,任何一个要使用系统资源的用户,都必须首先向 系统管理员申请一个账号,然后以这个账号的身份进入系统. 2.Linux 的用户 ...

  8. NSIS语法解析

    注释.!define.变量.!include.常量 ; Script generated by the HM NIS Edit Script Wizard. ; HM NIS Edit Wizard ...

  9. Windows 10专业版激活(附激活码)

    安全密钥:BT6TH-FN8VP-6WGCK-6BM9R-MWRDB(使用有效,在物理机,虚拟机都激活了一次) 六一八期间自己买了配件第一次组了台式机,系统是在123pe下的原版win10,装好机器之 ...

  10. 可持久化线段树的学习(区间第k大和查询历史版本的数据)(杭电多校赛第二场1011)

    以前我们学习了线段树可以知道,线段树的每一个节点都储存的是一段区间,所以线段树可以做简单的区间查询,更改等简单的操作. 而后面再做有些题目,就可能会碰到一种回退的操作.这里的回退是指回到未做各种操作之 ...