I asked the following a while ago, but only got back to the problem today. Further investigation has revealed that the problem is that the mouse enter event for the button isn't always firing. Most of the time it does, but either initially or after the button has been hidden (or collapses) the event doesn't fire. If I change to another case where the buttons should be enabled it does. Even setting the ZIndex
of the buttons to 9999 doesn't seem to help.
Old title:
Why isn't my button activation code always working?
I'm experimenting with a UI where certain buttons are only active under certain conditions and only become visible when the mouse moves over their location. (NOTE: I'm actually thinking of abandoning this approach but I'd like to know why my code isn't working.)
The problem I've got is that under some circumstances the button isn't activated.
The button isn't visible or active when I first run the program, but should become active (although invisible by dint of there being no text or image set) when an album is selected and there are other albums by the same artist.
However, this doesn't happen for the first qualifying album selected. If another album is selected which meets these criteria then the button does become visible and behaves correctly.
So it looks like something isn't initialised properly, but it's not obvious to me what I've missed.
I have the following 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>
Then in the "MouseEnter" handler I have the following:
private void NextAlbum_MouseEnter(object sender, MouseEventArgs e)
{
if (haveAlbum && moreAlbumsBySameArtist)
{
((sender as Button).Content as Image).Source = this.nextImage;
}
}
I've double checked and it's definitely getting to the line that sets the image source. It's just not displaying it.
The "MouseLeave" handler (for completeness is):
private void NextAlbum_MouseLeave(object sender, MouseEventArgs e)
{
((sender as Button).Content as Image).Source = null;
}
Then when an album is chosen I call the following code to make the next (and previous) album buttons selectable.
Visibility navigationVisiblity = haveAlbum && moreAlbumsBySameArtist
? Visibility.Visible : Visibility.Hidden;
this.NextAlbum.Visibility = navigationVisiblity;
The command handler NextCanExecute
is the same code:
private void NextCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = haveAlbum && moreAlbumsBySameArtist;
e.Handled = true;
}
(Yes, there is a case for refactoring here).
NOTE:
haveAlbum
is actually a test on !string.IsNullOrEmpty(this.albumPath.Text)
and
moreAlbumsBySameArtist
is a method call.
UPDATE
I've just tried changing the code to set the Opacity
of the image rather than setting the Source
and the same problem occurs. Further testing has revealed that it's the fact that the mouse over event handler isn't being called. I'm not adding or removing the handler at run time, so it looks like the system isn't firing the event?
Why would that be? Setting the Visibility
of the button clearly affects this - is there something I must call after setting it back to Visible
to get the event handlers wired up again?