【问题标题】:MouseEnter event does not fire on a Popup control after a mouse click on the Control鼠标单击控件后,MouseEnter 事件不会在 Popup 控件上触发
【发布时间】:2017-06-22 01:16:35
【问题描述】:

我正在使用以下代码在 WPF 中测试 Popup 控件

<Window x:Class="Popup1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Popup1"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="250">

    <Grid>
        <TextBlock  TextWrapping="Wrap">You can use a popup to provide a link for a specific 
            <Run TextDecorations="Underline" MouseEnter="ContentElement_OnMouseEnter">
                term
            </Run>
        </TextBlock>
        <Popup Name="popLink" StaysOpen="False" Placement="Mouse" MaxWidth="200"
           PopupAnimation="Slide" AllowsTransparency="True">
            <Border>
                <TextBlock Margin="10" TextWrapping="Wrap">
                For more information, see 
                <Hyperlink NavigateUri="http://en.wikipedia.org/wiki/Term" Click="Hyperlink_OnClick">Wikipedia</Hyperlink>
                </TextBlock>
            </Border>
        </Popup>
    </Grid>

</Window>

和处理程序

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

private void Hyperlink_OnClick(object sender, RoutedEventArgs e) {
    Process.Start(((Hyperlink) sender).NavigateUri.ToString());
}

结果是一个包含textblock 的普通窗口,其中包含指向弹出控件的链接,当鼠标悬停在指向弹出窗口的链接上时,该控件会直观地出现。 正常行为是弹出窗口保持可见直到鼠标单击。只要鼠标点击不在弹出窗口的链接上,它就可以正常工作

当我在弹出窗口的链接上单击鼠标时会发生我无法解释的奇怪行为。然后,弹出窗口关闭(如预期的那样)但当鼠标悬停在链接上时它再也不会出现(应该) .

你能解释一下这种行为吗?

【问题讨论】:

  • 对我来说,当popup.IsOpen 已经是true 但弹出窗口由于某种原因不可见时会发生这种情况。
  • 查看相关:stackoverflow.com/questions/24491382/invisible-opened-popup 所以在弹出窗口关闭和鼠标进入弹出窗口下方的文本块之间似乎存在竞争条件(因为它正在关闭),所以它会再次设置IsOpen=true而弹出关闭尚未完成。 (只是我对正在发生的事情的假设)

标签: c# wpf


【解决方案1】:

正如所评论的,原因可能是关闭弹出窗口和重新打开之间的竞争条件,因为鼠标位于文本块上。您可以通过延迟弹出打开操作直到当前工作完成来防止这种情况:

private void ContentElement_OnMouseEnter(object sender, MouseEventArgs e)
{
    Dispatcher.BeginInvoke(new Action(() => popLink.IsOpen = true));
}

关于您的标题文本:实际上已触发 MouseEnter 事件(调试它!),只是其中的操作没有按预期工作,因为弹出窗口处于不一致状态。

【讨论】:

  • 虽然您的建议解决了主要问题,但它会创建一个闪烁的弹出窗口(每次鼠标单击链接时,它会依次显示两次)。我也不明白您为什么使用 Dispatcher.BeginInvoke 方法和引用的延迟。在看到您上面的评论并进行一些调整后,我发现以下解决方案在视觉行为方面更好。
  • 我采用了解决方案,因为它兑现了承诺:每次鼠标进入时,都会打开弹出窗口。您更喜欢其他解决方案的原因是,因为您不喜欢您编写的程序。如果您不想在单击关闭时立即重新打开弹出窗口,您也可以更改调度程序调用:if (e.LeftButton != MouseButtonState.Pressed) Dispatcher.BeginInvoke(new Action(() =&gt; popLink.IsOpen = true)); 或按照您在链接中找到的方法进行操作。我认为无需重新发布链接的解决方案。
【解决方案2】:

经过一些调整后,如果我们为 Popup Close 事件添加一个额外的事件(与初始代码相比)处理程序,在弹出窗口关闭时将 IsOpen 属性设置为 false,则可以实现最佳行为

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

以及 XAML 中的修正

<Popup Name="popLink" StaysOpen="False" Placement="Mouse" MaxWidth="200"
       PopupAnimation="Slide" AllowsTransparency="True"
           Closed="PopLink_OnClosed">
        <Border Background="Bisque">
            <TextBlock Margin="10" TextWrapping="Wrap">
            For more information, see 
            <Hyperlink NavigateUri="http://en.wikipedia.org/wiki/Term" Click="Hyperlink_OnClick">Wikipedia</Hyperlink>
            </TextBlock>
        </Border>
    </Popup>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多