How can I use the RelayCommand in wpf?
Relay command doesn't exist in WPF, it is just a external class that raised to prominence after it was defined in this MSDN article. You need to write it yourself if you want to use it.
Otherwise you can you the Delegate command from the WPF toolkit here which has a little bit of extra functionality over the RelayCommand code.
Ah, the question changed while I was typing this answer. Assuming that you are using the RelayCommand as defined above you need to supply it with one or two delegates, one that returns a bool which determines whether the command is in a valid state to be run, and a second which returns nothing and actually runs the command. If you don't supply a "CanRun" delegate then the command will consider that it is always in a valid state. The code used in the article:
RelayCommand _saveCommand;
public ICommand SaveCommand
{
get
{
if (_saveCommand == null)
{
_saveCommand = new RelayCommand(param => this.Save(),
param => this.CanSave );
}
return _saveCommand;
}
}
Declares a RelayCommand that will call the Save() method when triggered and return the CanSave property as a test for validity. When this command is bound to a button in WPF the IsEnabled property of the Button will match the CanSave property of the ViewModel and when the button is clicked (assuming it is enabled) the Save() method will be called on the ViewModel.
As an alternative to creating RelayCommand wrappers for all your methods can I suggest a free library and source that will allow you to use the binding {BindTo Save()}. I created it to simplify my bindings. It also makes relative binding much easier. You can find it here: http://www.simplygoodcode.com/2012/08/simpler-wpf-binding.html
Related
This may be an X-Y problem. Please don't hesitate to tell me if I'm completely off-base here.
First, a simplified example of the kind of situation I am thinking of.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace XXXXXXX
{
public class AbstractOperation : INotifyPropertyChanged
{
public enum OpState { Init, Running, Aborted, Completed, Errored };
OpState privateOperationState;
public OpState OperationState
{
get => privateOperationState;
private set
{
if(privateOperationState!=value)
{
privateOperationState = value;
OnPropertyChanged();
}
}
}
public bool IsRunning => OperationState == OpState.Running;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
public class BackgroundOperator
{
AbstractOperation whatever;
public bool IsRunning => whatever.IsRunning;
public AbstractOperation.OpState OperationState => whatever.OperationState;
}
}
AbstractOperation is to be a base class representing some multi-step operation that takes significant time to perform. It will expose the status of it's operation through some properties.
BackgroundOperation is a class that will take an AbstractOperation and run it in a background thread, passing through some of the status properties. I want to be able to bind some UI element properties to these operations so that, for example, a certain control is disabled while the operation is running. I understand that the INotifyPropertyChanged interface is necessary for bindings like this to work.
If I implement the PropertyChange event on just one property like this, will the notification automatically cover other properties that refer to this property in their body? Does it work only within the class, or does it still work with another class that owns an instance of the notifying class? Do I need to do some special code to link the referring properties to the original property's notification? Or am I deep into X-Y land here and should implement some other way of binding UI controls to the status of my operation?
If I implement the PropertyChange event on just one property like this, will the notification automatically cover other properties that refer to this property in their body?
What happened when you tried it? Did you get property change notification for other properties?
Does it work only within the class, or does it still work with another class that owns an instance of the notifying class?
It doesn't do that at all, so it won't do it in any other class.
Property change notification isn't magic. It just raises the event, setting the name value in the event args object to the one you passed in to the OnPropertyChanged() method (in this case, implicitly via the [CallerMemberName] attribute).
All that said, using properties like this isn't necessarily the best way to deal with disabling commands. You don't say what API you're actually using, but a common one that uses this sort of pattern is WPF. It uses ICommand bindings for commands. The ICommand.CanExecute() method should be used to indicate whether a command is valid at a given time. ICommand.CanExecuteChanged should be raised when the value for that method changes. This is typically done by whatever code begins an operation or changes some state that would render the command invalid at that time. The same code would then change the CanExecute() state back to valid when it's done.
The exact mechanism for changing the command state and raising its event depends on how you implement the command. There are lots of examples out there, which you should review. See what works best for you.
If you are using some other API, it may or may not have a similar mechanism. It's not possible to know what the best answer along those lines would be, since that information is not available in your question.
I am new to the MVVM pattern and I am trying to write my own custom Commands. What is the best method to write custom commands? (I read a lot of articles here and there, but could not obtain the idea of creating my commands). And in particular if someone can help me with the idea of creating a command, after a button is clicked to get the items from one ListView and put them in another. (The list view is bounded to ObservableCollection). Thanks in advance!
Just implement the ICommand interface. There are many on the web or even implemented in nuget packages. Search for RelayCommand or DelegateCommand with ICommand and you will find many implementations. After you have that you just wrap the VMs private method in a command. e.g.
ICommand startTestCommand;
public ICommand StartTestCommand { get { return startTestCommand ?? (startTestCommand = new RelayCommand(StartTest)); }
private void StartTest()
{
//This will execute if the Command is bound in XAML
}
To bind the command in XAML (assuming your view model is the data context) just bind the Command property of the button to "StartTestCommand" or whatever your command is called.
So in essence you do not "Create your own command" for what you are asking, but wrap the delegate for a Command mediator to handle preventing coupling. There are reasons to create your own commands, but I would recommend using what is out there.
You just have to implement the ICommand interface. Most MVVM frameworks have a generic delegate based command class which implements it (e.g. RelayCommand in MVVM light). You just pass the methods to execute to their constructor.
I'm just starting out with WPF and I want to use custom commands whenever possible as part of the MVVM pattern. The book that I've been using (C# 2010 All-in-One for Dummies) has a sample of a custom command but it uses hard coded information to complete its task and I don't see how to use the Command system to complete my task.
Book Code:
public abstract class CommandBase : ICommand
{
public string Text { get; internal set; }
public abstract void Execute(object parameter);
public abstract bool CanExecute(object parameter);
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
public class AddCustomerCommand : CommandBase
{
public AddCustomerCommand()
{
Text = “Add Customer”;
}
public override void Execute(object parameter)
{
var list = parameter as IList<Customer>;
if (list == null)
{
return;
}
list.Add(new Customer { ID = 4, Name = “New Customer”} );
}
public override bool CanExecute(object parameter)
{
return parameter is IList<Customer>;
}
}
In this case, Execute works because it is passed an IList<Customer> and can add to it without needing to return anything. This makes perfect sense to me.
My Problem:
I have an MVVM app that has a data grid, some text boxes, and some buttons. My view model has IList<Entry> Entries, properties for the text boxes, and of course an instance of my custom command AddEntryCommand. The goal is to be able to enter text, and hit add, and have a new Entry be added to Entries using AddEntryCommand.
What I don't understand is how to go about getting Entries and the new data into the command. Here are the possible solutions I've thought of and what I see wrong with them
Pass in the view model so that all its information is available.
Pass in an array of objects.
Pass in a Tuple.
Passing thew view model seems excessive, and if I do that then everything on the view model would have to be mutable.
I try and avoid using object whenever possible, and object[] seems even more work to deal with. I'd have to pick it apart like command line arguments.
Tuples...
My idea of a command is that it's supposed to be a method with bells and whistles for making the UI react nicely. Anything that causes the command to be tied to a specific view or view model breaks that.
So my questions are:
How do you do work with multiple objects using ICommand?
How can you use ICommand to work with immutable objects if it's locked to return void?
Is my idea of what a command is for way off base?
(I've tried searching for a better tutorial or resource for this but my Google fu is weak and I can't seem to locate anything that's clear and concise. There are lots of questions on SO about commands in WPF, but they're all for very specific implementations. I'm looking for a general answer regarding manipulating multiple objects in one command.)
UPDATE
I have been looking around the net some more but I still haven't found anything like the sample provided by my book. I have looked at DelegateCommand and that seems like a pretty straightforward and easy to use system. It still leaves me wondering why such a large chunk of the chapter on MVVM would be dedicated to creating a custom command using just ICommand and not one of the other classes that already inherit from it.
I have gone through few MVVM examples in SL/WPF and the very basic thing here is to implement ICommand interface. I have understood how MVVM works. However, I have a doubt regarding Execute method of ICommand interface.
The class which implements ICommand has Execute method as shown below.
public void Execute(object parameter) //Method to call when the command is invoked
{
// pointer to a method to be executed
}
In every example, I see that parameter in above method is NULL. Why? Can someone post a simple example of MVVM where this object parameter is put to use and not null ?
In the XAML you can set a CommandParameter
<Button Command="{Binding MyCommand}" CommandParameter="SomeData" />
I'm currently toying a little with MVVM pattern and trying commands. I find the default way (every Command class needs to implement from ICommand interface) quite boring, so I've created a new base class called, wait for it, CommandBase. It looks like this:
public abstract class CommandBase : ICommand
{
public virtual bool CanExecute(object parameter)
{
return true;
}
public virtual event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public virtual void Execute(object parameter)
{
}
}
Now every command just inherits from this base class and overrides what is necessary. I had a bug in the software, so I've put several breakpoints in my inheriting class and in this base class. Everything seems to work as expected, except one thing - the method CanExecute gets fired all the time. If I put the breakpoint inside the method, my application won't even start! If I delete this breakpoint, everything works again.
MainViewModel:
public class MainViewModel : ViewModelBase // base implements INotifyPropertyChanged
{
public ICommand NavigateCommand { get; private set; }
public MainViewModel()
{
NavigateCommand = new NavigateCommand(this);
}
}
My debugger gets to the constructor, instantiate the Command class and from now on the method CanExecute fires like crazy and I can't even open the application window, because the vs debugger won't let me. In my NavigateCommand I only override Execute method and set one property of the MainViewModel, nothing too fancy. CanExecute is left intact without overriding.
Just a note, the bug I've mentioned was just a typo of my View, it wasn't related to this issue. After I've fixed it, code works except this thingy.
Can someone provide an explanation why it behaves like this?
It's a 'normal' behavior, that CanExecute gets fired often by the CommandManager. You shouldn't try to debug into this methods. In case of unknow bugs, turn on the Common Language Runtime Exceptions at Debug -> Exceptions... Further information here.
Can I suggest that, unless absolutely necessary, you don't need to reinvent the wheel here. There are a number of excellent implementations of ICommand out there that you can use.
RelayCommand is probably the most commonly used, although DelegateCommand is also very well implemented, and is the standard ICommand implementation is the Prism framework.