问题
I created a button whose commandparameter is set and command using a class that implements ICommand interface. But my button is disabled. Why is that? I got this code from here: ICommand is like a chocolate cake
<Window x:Class="ICommand_Implementation_CSharp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ICommand_Implementation_CSharp"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid>
<Grid.Resources>
<local:HelloWorldCommand x:Key="hwc" />
</Grid.Resources>
<Button Command="{StaticResource hwc}" CommandParameter="Hello"
Height="23" HorizontalAlignment="Left" Margin="212,138,0,0"
Name="Button1" VerticalAlignment="Top" Width="75">Button</Button>
</Grid>
</Grid>
and my class is
class HelloWorldCommand:ICommand
{
public bool CanExecute(object parameter)
{
return parameter != null;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
MessageBox.Show(parameter.ToString());
}
}
回答1:
Well, this is very-very simple implementation of ICommand
.
As @JleruOHeP says, partially problem can be solved by swapping setters of Command
and CommandParameter
. But this is ugly way, because you have to remember the sequence every time.
More correct way is to tell CommandManager
to re-query states of command:
public class HelloWorldCommand : ICommand
{
public bool CanExecute(object parameter)
{
return parameter != null;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
MessageBox.Show(parameter.ToString());
}
}
Now the sequence of setters is indifferent.
To understand how CommandManager
works, you can read this nice article from Josh Smith.
回答2:
The simplest answer - switch places of Command and Command parameter:
<Button CommandParameter="Hello" Command="{StaticResource hwc}" .../>
But better one is given by @Dennis
回答3:
In my case it was the CommandParameter
type that was causing the issue. My button was simply bound like this:
<Button Content="New" Command="{Binding NewCommand}" CommandParameter="False" />
The underlying NewCommand
is a RelayCommand<bool>
. Somehow XAML was not able to translate False
to bool. (Note that it does work for many built-in types and properties; maybe some TypeConverter
or something at action there).
Solution was to simply spoon-feed XAML about the real underlying type of CommandParameter
, like this:
<Button Content="New" Command="{Binding NewCommand}">
<Button.CommandParameter>
<sys:Boolean>
False
</sys:Boolean>
</Button.CommandParameter>
</Button>
You have to import sys
namespace at the top of your XAML file, like this:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Hope this helps someone down the road.
来源:https://stackoverflow.com/questions/12104274/button-not-enabled-even-after-providing-commandparameter-in-wpf