【问题标题】:Why isn't the MouseEnter event firing?为什么 MouseEnter 事件没有触发?
【发布时间】:2011-04-04 18:11:42
【问题描述】:

进一步调查显示,问题在于按钮的鼠标输入事件并不总是触发。大多数情况下它会发生,但无论是最初还是在按钮被隐藏(或折叠)之后,事件都不会触发。如果我更改为应该启用按钮的另一种情况。即使将按钮的 ZIndex 设置为 9999 似乎也无济于事。

我已重写代码以使用绑定来设置按钮图像源和可见性,但问题仍然表现出相同的症状。

当鼠标移到按钮上第一次应该可见(但不显示图像)时,它们不会显示工具提示或出现。如果我使用键盘/鼠标键循环到不同的专辑,按钮开始起作用。如果我再次选择并且下一位艺术家有多个专辑,则按钮开始起作用。


旧标题:

为什么我的按钮激活码不总是有效?

我正在试验一个 UI,其中某些按钮仅在某些条件下处于活动状态,并且仅在鼠标移到其位置时才可见。 (注意:我实际上正在考虑放弃这种方法,但我想知道为什么我的代码不起作用。

我遇到的问题是在某些情况下按钮没有被激活。

在我第一次运行程序时,按钮是不可见的或活动的,但应该变得活跃(尽管所选的一张专辑时,虽然没有文本或图像集的DINT,但同一艺术家还有其他专辑.

但是,这不会发生在所选的第一张符合条件的专辑中。如果选择了另一个满足这些条件的专辑,则按钮确实变得可见并且行为正确。

所以看起来有些东西没有正确初始化,但对我来说我错过了什么并不明显。

我有以下 XAML:

<BitmapImage x:Key="NextAlbumSource" CacheOption="OnLoad"
             CreateOptions="IgnoreImageCache" UriSource="resources/next.png"/>


<Window.CommandBindings>
    <CommandBinding Command="{x:Static local:AlbumChooser.Next}"
                    CanExecute="NextCanExecute" Executed="NextExecuted" />
</Window.CommandBindings>


    <Button Height="50" Width="50" Margin="0,0,10,155"
            Command="{x:Static local:AlbumChooser.Next}" Name="NextAlbum"
            ToolTip="Next Album" HorizontalAlignment="Right"
            VerticalAlignment="Bottom"
            MouseEnter="NextAlbum_MouseEnter" MouseLeave="NextAlbum_MouseLeave">
        <Image />
    </Button>

然后在“MouseEnter”处理程序中,我有以下内容:

    private void NextAlbum_MouseEnter(object sender, MouseEventArgs e)
    {
        if (haveAlbum && moreAlbumsBySameArtist)
        {
            ((sender as Button).Content as Image).Source = this.nextImage;
        }
    }

我已经仔细检查过,它肯定会到达设置图像源的行。它只是没有显示它。

“MouseLeave”处理程序(为了完整性):

    private void NextAlbum_MouseLeave(object sender, MouseEventArgs e)
    {
        ((sender as Button).Content as Image).Source = null;
    }

然后选择相册时,我调用以下代码来制作下一个(和上一个)相册按钮。

        Visibility navigationVisiblity = haveAlbum && moreAlbumsBySameArtist 
            ? Visibility.Visible : Visibility.Hidden;
        this.NextAlbum.Visibility = navigationVisiblity;

命令处理程序NextCanExecute是相同的代码:

private void NextCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = haveAlbum && moreAlbumsBySameArtist;
    e.Handled = true;
}

(是的,这里有重构的案例)。

注意:

haveAlbum实际上是对!string.IsNullOrEmpty(this.albumPath.Text)的测试

moreAlbumsBySameArtist 是一个方法调用。

更新

我刚刚尝试更改代码以设置图像的Opacity,而不是设置Source,并且发生了同样的问题。进一步的测试表明,鼠标悬停事件处理程序没有被调用。我没有在运行时添加或删除处理程序,所以看起来系统没有触发事件?

为什么会这样?设置按钮的 Visibility 显然会影响这一点 - 在将其设置回 Visible 后我必须调用什么来重新连接事件处理程序吗?

【问题讨论】:

标签: c# wpf button visibility


【解决方案1】:

在某些情况下,CommandBinding 上的 NextCanExecute 方法可能会返回 false,从而禁用您的按钮。

【讨论】:

  • 我应该补充一点,NextCanExecute 使用与可见性代码相同的测试。我会仔细检查,但我也会更新问题。
  • 对于 e.CanExecute 是否返回 true?
  • 当我尝试调试时,代码出现 会自行运行。很难确定,因为我正在更新 UI,并且当应用程序失去并重新获得焦点时会触发这些事件。但是,如果我逐步执行这些方法,一切都会返回预期值。
  • 这很奇怪。我已经测试了当您的按钮折叠时命令绑定是否仍然会触发,并且确实如此。您可以尝试调用 CommandManager.InvalidateRequerySuggested();以便从一开始就触发您的命令绑定?
【解决方案2】:

在这种情况下可能存在一些陷阱。由于 MouseEnter 和 MouseLeave 是 RoutedEvents,它们可能由其他元素处理。 使用 DragMove() 进行拖动时也存在问题。它可以防止所有这些事件在拖动时被触发。

【讨论】:

  • 我发现了一些关于 RoutedEvents 的信息 - 我不确定它是否适用,但既然你提到了它,我会再次检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多