第二天就解决这个问题。
要重现,请创建新的 WPF 应用程序 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>
and code
private void Button_MouseMove(object sender, MouseEventArgs e)
{
popup.IsOpen = true;
}
鼠标悬停按钮可打开弹出窗口,单击其他位置可关闭。点击按钮有bug:弹出的是是否打开 == true(可以在复选框上或处理程序中的断点上看到),但它是不可见的。
WTF?
我最初的问题似乎是setting IsOpen
不是即时的。例如,当我尝试将其设置为false
in Popup
's MouseMove
事件,然后我得到MouseEnter
and MouseMove
的事件Button
在那期间被解雇了
IsOpen = true;
与将其设置为相同true
, 有2个 (!)MouseMove
事件发生,将此行放入事件处理程序中以查看它
System.Diagnostics.Trace.WriteLine("M");
将会有2MOutputVS 的窗口,同时Popup
(when StayOpen=false
)假设捕获鼠标事件并且确实如此,但是不立即.
有人可以解释一下这是怎么回事吗?我不希望任何事件发生during(或不久之后?如何检查这是否属实?)设置IsOpen
。已经尝试了几十件事:Dispatcher.InvokeAsync
、变量、定时器等
我认为您的异步假设是正确的。在焦点丢失期间,值IsOpen
设置为 false,但是MouseMove
按钮触发将其再次打开。然后里面有一些奇怪的魔法打破了代码。
我找到了两种可能的解决方案,具体取决于您的需求:
- 显式设置
IsOpen
to false
,弹出窗口关闭后(bash 异步)
- #1 + 在弹出窗口期间禁用按钮
IsOpen == true
第一种方法将在单击按钮时隐藏弹出窗口。第二种方法会伴随轻微的闪烁 - 当快速单击按钮时 - 但它会保持弹出窗口打开:
对于第一种方法,请使用以下事件处理程序(您可能不会先检查属性):
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
并将其以一种方式绑定到弹出窗口:
IsEnabled="{Binding (Popup.IsOpen), ElementName=popup, Converter={StaticResource BoolInvertConverter}, Mode=OneWay}"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)