有什么方法可以阻止 WPF 弹出窗口在离开屏幕时重新定位自身吗?
有没有办法阻止 WPF 弹出窗口< /a> 当它离开屏幕时不会重新定位自己?
我发现这个老问题,但没有得到适当的解决回答它。有什么办法可以做到这一点吗?如果有必要,我愿意将其子类化。谢谢。
Is there any way to stop a WPF Popup from repositioning itself when it goes off-screen?
I found this old question, but it didn't get a proper answer to it. Is there any way to do this? I'm willing to subclass it if necessary. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
正如 Andrei 指出的那样,这种行为深藏在
Popup
控件内部,很难克服。如果您愿意做一些工作,可以通过在弹出窗口到达屏幕边缘时调整其大小和翻译弹出内容来完成。出于演示目的,我们将重点关注屏幕的左边缘。如果我们有一些像这样的 XAML:
和像这样的代码隐藏:
然后通过计算
Popup
将离开屏幕,我们可以减少内容的宽度并给它一个负边距,以便如果Popup
允许的话,屏幕上的部分会被剪切到显示的内容。这必须扩展以处理屏幕的所有四个边缘以及多个屏幕的可能性,但它表明该方法是可行的。
As Andrei points out, this behavior is deep inside the
Popup
control and hard to overcome. If you are willing to do some work it can be done by resizing and translating the content of the popup when it reaches the screen edges. For the purposes of the demonstration, we'll focus on the left edge of the screen.If we have some XAML like this:
and code-behind like this:
then by calculating that the
Popup
would be off-screen, we can reduce the width of the content and give it a negative margin so that the portion that is on-screen is clipped to what would have appeared if thePopup
were to allow this.This would have to be extended to deal with all four edges of the screen and the possibility of multiple screens, but it demonstrates that the approach is workable.
我认为没有办法做到这一点。至少是一种干净的方式。如果您使用 Reflector 查看 Popup 类,您会发现一个
UpdatePosition
方法,该方法将调整弹出窗口的位置,使其保持在屏幕边界之间。此方法是从多个位置调用的,例如On***Changed
回调(OnPlacementChanged
、OnVerticalOffsetChanged
等)。如果您真的很想获得此功能,您可能有机会扩展 Popup 类,覆盖使用
On***Changed
回调注册的属性上的一些元数据,以便UpdatePosition
永远不会被调用,但是大多数人会认为这样做是纯粹的邪恶,我也不推荐它。I don't think there is a way to do this. At least a clean way. If you peek to the Popup class with the Reflector, you'll find an
UpdatePosition
method that will adjust the location of the popup so that it stays between screen bounds. This method is called from several places, fromOn***Changed
callbacks (OnPlacementChanged
,OnVerticalOffsetChanged
, etc).If you're really really want to get this functionality, you might have a small chance to extend the Popup class, override some of the metadata on the properties that registered with the
On***Changed
callbacks so thatUpdatePosition
never gets called, however most people will consider doing this to be pure evil, I don't recommend it either.wpf 框架无法将 Popup 置于屏幕之外,但您可以通过 p/invoke 调用“SetWindowPos”来强制弹出位置:
there is no way on wpf framework to put Popup out of screen , but you can force popup position by calling "SetWindowPos" via p/invoke:
您可以使用 PrecisePopup 控件来自我的开源 JungleControls 库。它将按照指定的方式准确定位弹出窗口,即使这意味着弹出窗口部分位于屏幕外。
它可以自动从您定义的展示位置中选择最合适的展示位置,但如果您只需要一个与内置弹出窗口的“底部”位置相对应的精确弹出位置,您可以这样做:
You can use PrecisePopup control from my opensource JungleControls library. It will position the popup exactly as specified even if that means the popup is partially off-screen.
It can automatically select the most suitable placement from among the placements you define, but if you just need one exact popup placement that corresponds to "Bottom" placement of the built-in Popup, you can do it like this:
您必须将弹出窗口及其目标放置在 Canvas 面板内,这样它就不会由于弹出窗口控件中的屏幕边缘问题而重新定位。
由于整个单元位于画布面板内并且设置了放置矩形,因此弹出窗口将显示在矩形下方。
You have to place the popup and its target inside the Canvas panel so that it wont reposition due to the screen edge problem in popup control.
Since the whole unit is inside canvas panel and placement rectangle is set the popup will show below the rectangle.