【问题标题】:C# WPF OnMouseEnter and OnMouseLeave loopsC# WPF OnMouseEnter 和 OnMouseLeave 循环
【发布时间】:2020-11-01 08:14:31
【问题描述】:

我有 WPF UI 元素,当鼠标光标进入此元素时应隐藏,当鼠标光标离开此元素时可见。为此,我使用事件OnMouseEnter 和OnMouseLeave,如下所示:

private void TextBlock_MouseEnter(object sender, MouseEventArgs e)
{
    (e.Source as UIElement).Visibility = Visibility.Hidden;
}

private void TextBlock_MouseLeave(object sender, MouseEventArgs e)
{
    (e.Source as UIElement).Visibility = Visibility.Visible;
}

(以下代码来自https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.panel.zindex?view=netframework-4.8)

<Canvas>
            <Rectangle Canvas.ZIndex="1" Width="100" Height="100" Canvas.Top="100" Canvas.Left="100" Fill="blue" MouseEnter="TextBlock_MouseEnter" MouseLeave="TextBlock_MouseLeave"/>
            <Rectangle Canvas.ZIndex="2" Width="100" Height="100" Canvas.Top="150" Canvas.Left="150" Fill="yellow" MouseEnter="TextBlock_MouseEnter" MouseLeave="TextBlock_MouseLeave"/>
            <Rectangle Canvas.ZIndex="3" Width="100" Height="100" Canvas.Top="200" Canvas.Left="200" Fill="green" MouseEnter="TextBlock_MouseEnter" MouseLeave="TextBlock_MouseLeave"/>

            <!-- Reverse the order to illustrate z-index property -->

            <Rectangle Canvas.ZIndex="3" Width="100" Height="100" Canvas.Top="300" Canvas.Left="200" Fill="green" MouseEnter="TextBlock_MouseEnter" MouseLeave="TextBlock_MouseLeave"/>
            <Rectangle Canvas.ZIndex="2" Width="100" Height="100" Canvas.Top="350" Canvas.Left="150" Fill="yellow" MouseEnter="TextBlock_MouseEnter" MouseLeave="TextBlock_MouseLeave"/>
            <Rectangle Canvas.ZIndex="1" Width="100" Height="100" Canvas.Top="400" Canvas.Left="100" Fill="blue" MouseEnter="TextBlock_MouseEnter" MouseLeave="TextBlock_MouseLeave"/>
        </Canvas>

但是当我运行程序并将光标悬停在元素上时,it starts to flicker and eat up quite a lot of CPU resources.

调试显示当我将光标悬停在元素上时,events loops 直到我将光标移出元素。

我看到this article,但我不明白那里附上的解决方案。

我需要做些什么来防止这些事件循环?

【问题讨论】:

  • 它必须是代码隐藏吗?为什么不使用 XAML 的力量来解决呢?类似this 或this
  • 通过在鼠标光标进入时隐藏元素,鼠标不再位于(现在隐藏的)元素上方,因此触发了 MouseLeave 事件等等。

标签: c# wpf


【解决方案1】:

当您将 UIElement 的 Visibility 更改为 Hidden 时,您实际上触发了 MouseLeave 事件,因为现在在其后面的元素上执行了鼠标点击测试。然后运行您的事件处理程序,它将 Visibility 设置为 Visible,然后触发 MouseEnter 事件。因此闪烁。

解决这个问题的一个想法是使用不透明度而不是可见性。试试:

private void TextBlock_MouseEnter(object sender, MouseEventArgs e)
{
  (e.Source as UIElement).Opacity = 0;
}

private void TextBlock_MouseLeave(object sender, MouseEventArgs e)
{
  (e.Source as UIElement).Opacity = 1;
}

【讨论】:

    【解决方案2】:

    你可能会因为重复设置相同的值而导致“绘画事件”,试试这个,看看你是否满意

    private void TextBlock_MouseEnter(object sender, MouseEventArgs e)
    {
       if(e.Source is UIElement element && element.Visibility != Visibility.Hidden )
       {
         element.Visibility = Visibility.Hidden;
       }   
    }
    

    【讨论】:

    • 不,它不起作用。 element.Visibility != Visibility.Hidden 始终为真,因为事件循环(可见 -> 隐藏 -> 可见 ->...)
    • 不应该像你输入一次直到你离开它
    猜你喜欢
    • 2013-07-06
    • 2017-12-28
    • 2020-11-23
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-17
    相关资源
    最近更新 更多