failed to create a ‘System.Windows.Input.ICommand’ from the text - silverlight

hi in my silverlight5 and mvvm pattern,
i had one mainpage that page contains one button,
<Button Command="MyCommand"> Click Me </Button>
This above error can occur when binding a Command inside a Xaml file.
Why this error coming.. Any Help..

have you tried
<Button Command="{Binding MyCommand}"> Click Me </Button>

Solution is,
In fact, the problem with this syntax reside in the way we call the command. The previous example were not using the Binding syntax.
i used the Binding keyword.
<Button Command="{Binding MyCommand}"> Click Me </Button>
Of course, you need bind to a ICommand property to the desired command.
public ICommand MyCommand
{
get {
return ....
}
}

Related

Can I have both a code-behind Click event as well as a Command?

I'd like to know if I can have both a button click event in the code-behind, as well as a command in the viewmodel, and they both work? Like this:
<Button x:Name="CancelButton"
Command="{Binding CancelCommand}"
Content="Cancel" Click="CancelButton_Click" />
Sure you can. The Click event handler will be invoked and executed before the Execute method of the command.
Note that implementing any application logic in the Click event handler in the view effectively breaks the MVVM pattern though.

WPF Button Command, why logic code in ViewModel?

I have read some thread about how to work on WPF ListView command binding.
Passing a parameter using RelayCommand defined in the ViewModel
Binding Button click to a method
Button Command in WPF MVVM Model
How to bind buttons in ListView DataTemplate to Commands in ViewModel?
All of them suggest write the logic code inside ViewModel class, for example:
public RelayCommand ACommandWithAParameter
{
get
{
if (_aCommandWithAParameter == null)
{
_aCommandWithAParameter = new RelayCommand(
param => this.CommandWithAParameter("Apple")
);
}
return _aCommandWithAParameter;
}
}
public void CommandWithAParameter(String aParameter)
{
String theParameter = aParameter;
}
It is good practice or anyway so I can move the CommandWithAParameter() out of the ViewModel?
In principle, MVVM application should be able to run to its full potential without creating the views. That's impossible, if some parts of your logic are in View classes.
On top of that, ICommand has CanExecute, which will autamagically disable buttons, menu items etc. if the command should not be run.
I understand why with basic RelayCommand implementation it can be hard to see the benefits, but take a look at ReactiveCommand samples.
ReactiveCommand handles async work very well, even disabling the button for the time work is done and enabling it afterwards.
Short example: you have a login form. You want to disable the login button if the username and password are empty.
Using commands, you just set CanExecute to false and it's done.
Using events, you have manualy disable/enable the button, remember that it has to be done in Dispatcher thread and so on - it gets very messy if you have 5 buttons depending on different properties.
As for ListView, commands are also usefull - you can bind current item as command parameter:
<ListView ItemsSource="{Binding MyObjects}">
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<!-- change the context to parent ViewModel and pass current element to the command -->
<Button DockPanel.Dock="Right" Command="{Binding ElementName=Root, Path=ViewModel.Delete}" CommandParameter="{Binding}">Delete</Button>
<TextBlock Text="{Binding Name}"/>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Wpf MVVM button call method in view and view model also

In my MVVM application a have a button in a view.
When I press a button I want the run some method in the view, and also some method in the view model.
I connected come command to my button, so the command can run some method in the view model. But how can I run some method in view also?
I tried to connect a click event also, but it does not work.
What is the best way to run functions from view and viewmodel also.
Thanks,
You can do this entirely in XAML with interaction triggers:
<Button Content="Do Something" Click="OnClickHandler"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd ="http://www.galasoft.ch/mvvmlight">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding Path=ViewModelCommand1}" />
<cmd:EventToCommand Command="{Binding Path=ViewModelCommand2}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
In this case both the Window handler and each of the two viewmodel commands get invoked. If the handler sets e.Handled to true the viewmodel commands don't get called. If you set PassEventArgsToCommand="True" in the cmd:EventToCommand then you can specify a handler that accepts the args; setting Handled to true in the first viewmodel handler won't stop the second one being called but you can still check the value in the second handler manually.
Now, that said I would strongly encourage you to re-evaluate your architecture. Calling code-behind is not MVVM, and in over 7 years of doing this on a daily basis I have yet to see a single case where it was actually needed.
on the Click event, Execute command.
private void btnClick(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
btn.Command.Execute(btn.CommandParameter);
}
I would highly question your decision to "run both view and viewmodel method on button click". To me, it seems that what you want is that button runs a viewmodel command which in turn causes some change in view. What if for example it was possible to execute the method not through UI but from somewhere else in the application. Shouldn't the view change also?
For that I recommend creating an interface I[something]View, that the view will implement and which the view model have reference to. Then, the viewmodel can call the method on the interface which will do what you are expecting on the button click.

How to identify a source button in the bound method?

In my xaml file I bind button command as follows: ... Command="{Binding MyCommand}" ....
I use the 'well-known' RelayCommand in my view model to create the bound command as follows:
MyCommand = new RelayCommand(param => RunMyCommand())
How can I identify the source button in RunMyCommand()?
Thanks.
Well identify by what exactly? I wouldn't recommend identifying the button itself regardless, so try looking into CommandParameters. Bind or specify something as the CommandParameter and you can receive it into your command.

WPF CommandParameter binding to PasswordBox.Password

I have a MVVM run treeview. On the top level is an Account object that contains credentials. I have a PasswordBox that can be used to change the account password with a Save button right behind it. The code is as follows and is part of the Account level template:
PasswordBox Width="100" x:Name="pbPassword"/>
Button x:Name="btnSave" Command="{Binding ClickCommand}" CommandParameter="{Binding ElementName=pbPassword, Path=Password}" Height="20" Width="50">Save
I put something into the PasswordBox and then click Save. The ClickCommand fires, but the parameter is always string.Empty. What am I missing?
For security reasons, WPF doesn't provide a dependency property for the Password property of PasswordBox (reference 1, 2), so your command parameter binding doesn't work.
You could bind the command argument to PasswordBox, then access the appropriate property from within your command implementation:
<Button Command="{Binding ClickCommand}" CommandParameter="{Binding ElementName=pbPassword}">
// command implementation
public void Execute(object parameter)
{
var passwordBox = (PasswordBox)parameter;
var value = passwordBox.Password;
}
You may want to consider other options that do not involve keeping the password in memory as plain text.
Hope this helps,
Ben
--PLEASE STOP MARKING ME DOWN ON THIS, See comment below, this does not work, but left in so no-one else makes the same mistake--
Sorry old Q, but found an improvement on that
<Button Content="Log On"
Command="{Binding LogOnCommand}"
CommandParameter="{Binding ElementName=PasswordControl, Path=SecurePassword}" />
that way your command need only know about a SecureString object
public override void Execute(object parameter)
{
_viewModel.LogOnAsync((SecureString)parameter);
}
keeping knowledge of the ui from the command

Resources