隐形打开的弹出窗口 [英] Invisible opened popup

查看:94
本文介绍了隐形打开的弹出窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

第二天与这个问题作斗争.

Second day fighting this issue.

要进行复制,请创建新的WPF应用程序xaml

To reproduce, create new WPF application, xaml

<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
    <Button Width="100" Height="100" MouseMove="Button_MouseMove"/>
    <Popup x:Name="popup" StaysOpen="False" AllowsTransparency="True" Placement="Center">
        <TextBlock>Some random text</TextBlock>
    </Popup>
    <CheckBox IsChecked="{Binding (Popup.IsOpen), ElementName=popup}">Popup</CheckBox>
</StackPanel>

和代码

private void Button_MouseMove(object sender, MouseEventArgs e)
{
    popup.IsOpen = true;
}

鼠标悬停按钮以打开弹出窗口,单击其他位置以关闭.单击按钮出现错误:弹出窗口是 IsOpen == true (可以在复选框中看到,也可以在处理程序中带有断点),而它是不可见的.

Mouseover button to open popup, click elsewhere to close. Click button to have bug: popup is IsOpen == true (can be seen on checkbox or with breakpoint in handler), while it is invisible.

WTF?

而且我的原始问题似乎是,设置IsOpen并不是即时的.例如,当我尝试在PopupMouseMove事件中将其设置为false时,在此期间,我得到了ButtonMouseEnterMouseMove事件被触发

And my original problem is, it seems, what setting IsOpen is not instant. To example, when I try to set it to false in Popup's MouseMove event, then I get MouseEnter and MouseMove events of Button fired right during that

IsOpen = true;

与将其设置为true一样,有2个(!)MouseMove事件发生,请将此行放入事件处理程序中进行查看

Same with setting it to true, there are 2 (!) MouseMove events occurs, put this line into event handler to see it

System.Diagnostics.Trace.WriteLine("M");

VS的 Output 窗口中将有2 M,而Popup(当StayOpen=false时)假设是捕获鼠标事件并且捕获了鼠标事件,但是不是立即捕获 >.

There will be 2 M in the Output window of VS, while Popup (when StayOpen=false) suppose to capture mouse events and it does, but not immediately.

有人可以向我解释这是怎么回事吗?我希望在期间(或之后不久?如何检查是否为真?)设置IsOpen时不会发生任何事件.已经尝试了很多东西:Dispatcher.InvokeAsync,变量,计时器等

Can someone explain me what it going on? I want no events to occurs during (or shortly after? how to check if this is true?) setting IsOpen. Tried already dozens of things: Dispatcher.InvokeAsync, variables, timers, etc.

推荐答案

我认为您对异步假设是正确的.在焦点丢失期间,IsOpen的值设置为false,但是按钮的MouseMove触发以使其再次打开.里面有些奇怪的魔术破坏了代码.

I think you are right with the asynchronous assumption. During the focus loss, the value of IsOpen is set to false, but the MouseMove of the button triggers to set it open again. Some strange magic inside then breaks the code.

2种可能的解决方案,具体取决于您的需求:

2 possible solutions I found, depending on your needs:

  1. 在弹出窗口关闭后(bash异步)将IsOpen显式设置为false
  2. #1 +在弹出IsOpen == true
  3. 期间禁用按钮
  1. Explicitly set IsOpen to false, after the popup closed (bash async)
  2. #1 + Disable the button during the popup IsOpen == true

第一种方法是在单击按钮时隐藏弹出窗口.第二种方法会伴随着轻微的闪烁-快速单击按钮时-却使弹出窗口保持打开状态:

The first approach will hide the popup during clicking on the button. The second approach will come along with a slight flickering - when rapidly clicking the button - but it keeps the popup open:

对于第一种方法,请使用以下事件处理程序(您可能不会先检查该属性):

For the first approach, use the following event handlers (you might not check the property first):

private void Button_MouseMove(object sender, MouseEventArgs e)
{
    popup.IsOpen = true;
}

private void Popup_OnClosed(object sender, EventArgs e)
{
    if (popup.IsOpen)
        popup.IsOpen = false;
}

对于第二种方法,请使用BoolInvertConverter并将其绑定到弹出窗口的一种方式:

For the second approach, use a BoolInvertConverter and bind it one way to the popup:

IsEnabled="{Binding (Popup.IsOpen), ElementName=popup, Converter={StaticResource BoolInvertConverter}, Mode=OneWay}"

这篇关于隐形打开的弹出窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆