I am trying to bind the textbox text to Commandparameter. However in the call to CanExecute the parameter passed is null. Changing the text also does not call CanExecute.
Is my use case valid ?
View
<Window x:Class="PlayButtonCommandParameter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:playButtonCommandParameter="clr-namespace:PlayButtonCommandParameter"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<playButtonCommandParameter:TestViewModel x:Key="vm"/>
</Window.Resources>
<StackPanel DataContext="{StaticResource vm}">
<TextBox Name="Test">Hello</TextBox>
<Button Content="Element Name Click"
Command="{Binding TestCommand}"
CommandParameter="{Binding ElementName=Test, Path=Text}"></Button>
<Button Content="RelativeSource Click"
Command="{Binding RelativeSourceCommand}"
CommandParameter="{Binding
RelativeSource={RelativeSource AncestorType=StackPanel},
Path=Children[0].Text}"></Button>
</StackPanel>
</Window>
ViewModel
public class TestViewModel : INotifyPropertyChanged
{
private readonly ICommand testCommand = new TestCommand();
public ICommand TestCommand
{
get { return testCommand; }
}
private readonly ICommand relativeSourceCommand = new TestCommand();
public ICommand RelativeSourceCommand
{
get { return relativeSourceCommand; }
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Command
public class TestCommand : ICommand
{
public void Execute(object parameter)
{
Clipboard.SetData(DataFormats.Text, parameter);
}
public bool CanExecute(object parameter)
{
var text = parameter as string;
return !string.IsNullOrEmpty(text);
}
public event EventHandler CanExecuteChanged;
}
No your expectations are not valid. First:
no one is going to call your
CanExecute
handler unless you fire theCanExecuteChanged
event in your ICommand. In your case you will have to handle yourself theTextBox
TextChanged
event and raise theCanExecuteChanged
from within yourICommand
implementation.For this simple case i would suggest you to use a instance of a
RoutedCommand
instead. There is a CommandManager that listens for changes in the UI and will raise theCanExecuteChanged
event for you.Just follow this simple steps How to: Create a RoutedCommand