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?

[4565 byte] By [BillHenning2] at [2007-12-26]
# 1

You should use the CommandManager.InvalidateRequerySuggested(); method to update the button's state. CanExecute is used to determine whether a command can execute on an element but does not update enabled state of the Controls that are associated with that command. Actually, you can remove the other places where you call CanExecute because the input system automatically calls InvalidateRequerySuggested for you in those cases.

NeilKronlage-MSFT at 2007-9-4 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...

Visual Studio Orcas

Site Classified