views:

84

answers:

2

So say I have a button (MyButton) that binds to:

public ICommand MyCommand { get; set; }

I register this command with:

MyCommand = new DelegateCommand<object>(DoSomething);

Now if I do

MyButton.IsEnabled = false;

It doesn't do anything, i.e., the button is still enabled. I know that the command is causing this to happen because if I remove the new delegatecommand code above then the button appears disabled.

My questions are:
1. Is there a way for me to tell this binding to a command not to mess with my button's IsEnabled
2. Is there a way to change the visibility via only the commanding property (which would probably be the more correct way anyway)

Thanks!!

+1  A: 

You need to use the CanExecute event of the command object, and move your logic to the command object itself. This will be checked to tell if your button is enabled. You can read msdn ICommand documentation to read further about this function. Be sure to call CanExecuteChanged() whenever something occurs that causes the status to change.

Once a button uses a command, it is bound to that. You could hide the button by changing it's visiblity still if you prefer to do that.

Ryan from Denver
meh? I just want it to show as disabled. What logic should I move? it should just be a one liner, any hints apart from rtfm?
Shnitzel
It can be a one liner - very simple "return false;". It just has to be within your command object, which has a function called CanExecute(). A command basically does this: MyButton.IsEnabled = MyCommand.CanExecute() Hopefully that helps explain it.
Ryan from Denver
+2  A: 

You need to add logic into your command for the CanExecute delegate, e.g.:

ICommand comand = new DelegateCommand<object>
    (
    executeMethod: delegate { DoSomething(); }
    ,
    canExecuteMethod: delegate { return _buttonEnabled; }
    );

_buttonEnabled = false;

CommandManager.InvalidateRequerySuggested();

_buttonEnabled = true;

CommandManager.InvalidateRequerySuggested();

The "_buttonEnabled" variable should really represent the state of your application that controls whether the button should actually be enabled or disabled. For example, it could be "_isSomethingDone" and be true\false depending on the state of your application. This would then disable your button whilst "DoSomething" is actually doing something.

Rough example:

ICommand saveCommand = new DelegateCommand<object>
    (
    executeMethod: delegate { Save(); }
    ,
    canExecuteMethod: delegate { return _canSave; }
    );

private void Save()
{
    _canSave = false;

    CommandManager.InvalidateRequerySuggested();

    //do save...

    _canSave = true;

    CommandManager.InvalidateRequerySuggested();
}
chibacity
that's no big difference from my binding to a isenabled boolean
Shnitzel
In practice sort of, but the command pattern encapsulates the concept that a command can not always be executed. It's a pretty common concept, so in general the pattern works well. If you've come from WinForms (and I have) this can be difficult at first, but it does make sense. It has the added benefit that unit testing becomes easier as you no longer have UI concepts such as "isButtonEnabled". You just have a command and logic that you can test to make sure the command can and cannot execute given expected states.
chibacity
okay point taken, I thank you for detailed explanation. one last thing. executeMethod: delegate { DoSomething; } presents a syntax error if DoSomething is a method..
Shnitzel
@Shnitzel I free-styled the code, have now made sure it compiles. Chars. :)
chibacity
argh, CommandManager can't be found i'm still trying to figure out where that is.. i'm using silverlight btw... hrmmmm
Shnitzel