CanExecute calls to update button enabled states don't work in animation Completed event ha
I am running into a scenario where it seems like a bug with Buttons and Commands. I have a Button tied to a RoutedCommand so that the Button should update its enabled state based on the CanExecute value of the Command.
In this scenario, I have a boolean flag which represents some condition as to whether the command can execute or not. I have set up 3 Buttons on a Window with this code:
<Window x:Class="SampleApplication.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleApplication"
Title="SampleApplication" Height="300" Width="300"
>
<StackPanel>
<Button x:Name="targetButton" Command="local:Window2.MyCommand" Content="Button that will enable/disable" />
<Button Click="testButton_Click" Content="Click to test disabling during an animation" />
<Button Click="testSimpleToggleButton_Click" Content="Click to test a simple toggle" />
</StackPanel>
</Window>
Here is the codebehind for the Window:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace SampleApplication {
public partial class Window2 : System.Windows.Window {
public Window2() {
InitializeComponent();
}
private static RoutedCommand myCommand;
public bool flag = true;
private DoubleAnimation anim;
static Window2() {
myCommand = new RoutedCommand("DoSomething", typeof(Window2));
CommandManager.RegisterClassCommandBinding(typeof(Window2), new CommandBinding(myCommand, myCommand_Execute, myCommand_CanExecute));
}
public static RoutedCommand MyCommand {
get {
return myCommand;
}
}
private static void myCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
Window2 window = sender as Window2;
if (window != null)
e.CanExecute = window.flag;
else
e.CanExecute = false;
}
private static void myCommand_Execute(object sender, ExecutedRoutedEventArgs e) {
MessageBox.Show("Executed");
}
void anim_Completed(object sender, EventArgs e) {
flag = true;
myCommand.CanExecute(null, this);
Console.WriteLine("COMPLETE: " + flag);
}
private void testButton_Click(object sender, RoutedEventArgs e) {
flag = false;
myCommand.CanExecute(null, this);
Console.WriteLine("ANIMATION START: " + flag);
anim = new DoubleAnimation(0.5, 1.0, TimeSpan.FromSeconds(1));
anim.Completed += new EventHandler(anim_Completed);
targetButton.BeginAnimation(Button.OpacityProperty, anim);
}
private void testSimpleToggleButton_Click(object sender, RoutedEventArgs e) {
flag = !flag;
myCommand.CanExecute(null, this);
}
}
}
Now when you run the Window, if you click the bottom Button, it will flip the flag and call the command's CanExecute method which does update the enabled state of the top Button properly.
If you click the middle Button, it will set the flag to false, call CanExecute, and that also updates the top Button properly so that it disabled. Now the part that doesn't work. This event handler also sets off a simple animation that lasts for a second. We attach to the Completed event handler of the animation. In the animation's Complete event handler, we set the flag back to try, and call CanExecute again to update the top Button back to enabled but it doesn't work and stays disabled until you click on the top Button. It's like it refuses to repaint. The goal here is to disable the top Button while the animation is running and enable it when the animation is complete.
So in summary, if you try calling a command's CanExecute method in the Completed event handler of an animation, no buttons attached to the command will update their enabled state. Any ideas what is wrong here or is this a bug?

