WPF中Popup的几个问题
要用popup控件来解决一些问题。就此带来了一批问题。
问题一、 在popup外任意位置点击时要能关闭popup,这个本来简单,只要加上StaysOpen=false就可以了。但我的popup中有个OpenFileDialog控件,这个控件窗口一打开,popup就被关闭了。
解决:
在btnOpenFile按钮的PreviewMouseLeftButtonDown事件里添加了
((Popup)((FrameworkElement)this.Parent).Parent).StaysOpen = true;
问题二、 StaysOpen设置为True后,点击按钮变成了这样。popup是TopMost的,挡在了文件窗口前面。

解决:
无法简单解决这个问题,只好采用github上的一个NonTopmostPopup自定义控件取代Popup。
为了在关闭文件选择窗口后popup仍然能够在鼠标点击App任意位置时被关闭,在btnOpenFile按钮的Click事件里添加了
((Popup)((FrameworkElement)this.Parent).Parent).StaysOpen = false;
问题三、上述做法的结果是,如果双击文件名时的鼠标位置在popup区域以外,popup还是会直接关闭。因为双击位置的主窗口控件虽然被文件对话框遮挡,但仍会触发MouseLeftButtonUp(或MouseUp)事件,这可能算是文件对话框的一个bug。我猜是因为双击实际上是在第二次点击的MouseDown事件发生后就生效,对话框就关闭了,再往后还有MouseUp事件,却已经处于没有遮挡的裸奔状态了,当然控件们纷纷响应。
没办法,想workaround吧。我的做法是取消按钮Click事件StaysOpen=false,改在主窗口的MouseLeftButtonDown中加下面的代码遍历控件,遇到popup就设置StaysOpen=false。
private void TheShell_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
FindPopupAndClose(TheShell);
} // Enumerate all the descendants of the visual object.
static public void FindPopupAndClose(Visual myVisual)
{
for (int i = ; i < VisualTreeHelper.GetChildrenCount(myVisual); i++)
{
// Retrieve child visual at specified index value.
Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i); // Do processing of the child visual object.
if (childVisual is Popup)
((Popup)childVisual).StaysOpen = false;
// Enumerate children of the child visual object.
FindPopupAndClose(childVisual);
}
}
问题四、一些情况下,我需要popup StaysOpen=false,并且能跟随主窗口移动而移动(默认情况popup是不动的)。
解决:
参考StackOverFlow上的帖子,在codebehind加下面事件:
public partial class View1 : UserControl
{
// Constructor
public View1()
{
InitializeComponent(); // Window.GetWindow() will return Null if you try to call it here! // Wire up the Loaded handler instead
this.Loaded += new RoutedEventHandler(View1_Loaded);
} /// Provides a way to "dock" the Popup control to the Window
/// so that the popup "sticks" to the window while the window is dragged around.
void View1_Loaded(object sender, RoutedEventArgs e)
{
Window w = Window.GetWindow(popupTarget);
// w should not be Null now!
if (null != w)
{
w.LocationChanged += delegate(object sender2, EventArgs args)
{
var offset = myPopup.HorizontalOffset;
// "bump" the offset to cause the popup to reposition itself
// on its own
myPopup.HorizontalOffset = offset + ;
myPopup.HorizontalOffset = offset;
};
// Also handle the window being resized (so the popup's position stays
// relative to its target element if the target element moves upon
// window resize)
w.SizeChanged += delegate(object sender3, SizeChangedEventArgs e2)
{
var offset = myPopup.HorizontalOffset;
myPopup.HorizontalOffset = offset + ;
myPopup.HorizontalOffset = offset;
};
}
}
}
小小的popup这才算整听话了。
WPF中Popup的几个问题的更多相关文章
- WPF中Popup控件在Win7以及Win10等中的对齐点方式不一样的解决方案 - 简书
原文:WPF中Popup控件在Win7以及Win10等中的对齐点方式不一样的解决方案 - 简书 最近项目中使用弹出控件Popup,发现弹出框的对齐方式在不同的系统中存在不同(Popup在win10上是 ...
- 关于WPF中Popup控件的小记
在wpf开发中,常需要在鼠标位置处弹出一个“提示框”(在此就以“提示框”代替吧),通过“提示框”进行信息提示或者数据操作,如果仅仅是提示作用,使用ToolTip控件已经足够,但是有些是需要在弹出的框中 ...
- WPF中Popup等弹窗的位置不对(偏左或者偏右)
1.情况如图: 正常情况: 部分特殊情况: 在一般的电脑都能正确显示,就是第一种情况,同样的代码为什么在不同的电脑就会显示不同的位置呢,原来Windows为了满足 不同需求的用户,左撇 ...
- 关于wpf中popup跟随鼠标移动显示
最近在做一个画图工具,里面有一个功能是需要实现,当鼠标移动的时候在,鼠标的旁边显示坐标信息. 第一反应是想到了tooltip,但是tooltip有许多的限制,查询资料的过程中看到了popup,popu ...
- WPF中Popup上的textbox无法切换到中文输入法
As Marco Zhou has said in the msdn forum (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/b ...
- 关于WPF中Popup中的一些用法的总结
Popup控件是一个常用的非常有用的控件,顾明思义就是弹出式控件,首先我们来看看MSDN对它的解释吧,表示具有内容的弹出窗口,这个是非常重要的控件,我们看看它的继承关系吧: System.Object ...
- WPF中Popup控件的使用
一.Popup控件的主要属性 Popup表示具有内容的弹出窗口,其主要属性为: Child:获取或设置 Popup控件的内容. IsOpen:获取或设置一个值,该值指示Popup 是否可见 Place ...
- 让WPF的Popup不总置顶的解决方案
使用WPF的Popup的时候会发现有一个问题,它总是会置顶,只要Popup的StayOpen不设置为False,它就一直呆在最顶端,挡住其他的窗口. 解决方案是继承Popup重新定义控件PopupEx ...
- wpf之Popup弹出自定义输入"键盘"
在很多工厂的信息化MES系统中,车间的采集数据的机器是触摸屏电脑(工厂环境所限,用外接鼠标键盘反而不方便). 由于没有外接键盘,所以用户无法像坐在办公室一样,用鼠标键盘进行录入信息. 这时我们可以用w ...
随机推荐
- 【JAVA】JDK -Calendar 遇到的 一个坑
Calendar是JDK 1.1增加的类 最近使用了下Calendar发现几个很让人抓狂的问题 源码: public final static int SUNDAY = 1; public final ...
- ArrayFire与CUDA环境配置问题
1.ArrayFire与cuda版本不一致时的解决方案 以Visual Studio2013为例,在工程-属性-C/C++--预处理加入宏AFCL,即可解决.
- STM32之位绑定
有32个美女给你,你32个一起处理是不是有点棘手呀??没事..那就一个一个“慢慢”来..为何我这里慢慢要加双引号?因为其实处理一个比处理32个要快很多很多..好,停住这美好的遐想,来认识下<位绑 ...
- requirejs:研究笔记
模块化历史 模块化异步加载方式 后期维护 查找问题 复用代码 防止全局变量的污染 http://requirejs.cn/ http://requirejs.org/ 我的目录结构 总体步骤 < ...
- Markdown常用语法
什么是Markdown Markdown 是一种方便记忆.书写的纯文本标记语言,用户可以使用这些标记符号以最小的输入代价生成极富表现力的文档. 通过Markdown简单的语法,就可以使普通文本内容具有 ...
- vb6保存项目到c盘的安装目录
工程保存在安装目录("C:\Program Files (x86)\Microsoft Visual Studio\VB98\errhandler1.vbp")里. 文件管理器找不 ...
- 百度网盘生成二维码api
分享出自精神,灵感来自大脑,在百度云网盘分享每一个文件,都会在页面生成一个二维码扫描的图片: 我就进一步看了该图片的地址: 发现没有,圈圈内是不是有点眼熟,就跟其他二维码api接口一样,只要盗用这段东 ...
- C# 程序实现功能目录
1.根据年月日获取 星期几 http://www.cnblogs.com/liwp/p/5943226.html 2.json对象转换为泛型集合 http://www.cnblogs.com/liw ...
- javascript入门:prototype和面向对象的实现
由于工作需要,需要大量使用javascript,于是对其进行了一下学习. 学习任何一个语言,最重要的是掌握其和其他语言不同的关键特性.对javascript来说,我总结就是prototype.就像me ...
- nginx服务器配置
nginx主要配置 #定义Nginx运行的用户和用户组user www www; #每个worker进程绑定到指定CPU ,均衡各CPU 负载worker_cpu_affinity 000000000 ...