I have a ViewModel that uses a DelegateCommand property to bind to a Button's Command property.
The problem is my sample data does not like the DelegateCommand object. It complains that: The type "DelegateCommand" does not include any accessible constructors. Also, the only exposed property is the IsActive property.
<local:MyViewModel xmlns:local="clr-namespace:MyNamespace"
xmlns:prism="http://www.codeplex.com/prism">
<local:MyViewModel.Age>47</local:MyViewModel.Age>
<local:MyViewModel.PurchaseAlcohalCommand>
<prism:DelegateCommand IsActive="True" />
</local:MyViewModel.PurchaseAlcohalCommand>
</local:MyViewModel>
Change your view model to expose an ICommand instead of a DelegateCommand. DelegateCommand is just an implementation of ICommand; if you later want to switch to RelayCommand from MvvmLight your view and your sample data should not have to care.
I'm not sure that this will solve your problem, but I suspect it might. Plus it's just a good programming practice.
The way your DelegateCommand is setup, it won't do anything when it is activated. If that is the desired behavior, my suggestion would be to simply not declare it. WPF will gracefully handle being bound to a null ICommand object.
Alternatively, if you need it to bind to an instantiated DelegateCommand, you could subclass DelegateCommand to include a parameterless constructor.
If you wanted it to bind to a DelegateCommand and you wanted that DelegateCommand to actually DO something when the command is triggered, that would get a bit more complicated. You would have to use the subclassed DelegateCommand I mentioned before, but you would also have to be able to define a delegate in XAML. I think there are samples out there, but I would guess they involve things like markup extensions and things of those nature. Your return on investment in this approach may be a little low, but your mileage may vary.
One last alternative that is the way this is typically handled: define your DelegateCommands in the constructor of your ViewModel.
Related
I am using a 3rd party WPF control whose MVVM support relies on dependency properties on the VM it is bound to. The sample that comes with the control uses a ViewModelBase class derived from DependencyObject so all is well.
My ViewModelBase implements INotifyPropertyChanged and for various reasons it is unrealistic to change it to DependencyObject.
My question is how do I use my ViewModels with this WPF control? I guess what I need is something like "embedding a dependencyobject" or "plugging dependency properties" in a plain old ViewModel.
By the way my MVVM application is interface based, i.e. everywhere SomeViewModel is ISomeViewModel.
In general, a properly designed control shouldn't require binding to a DependencyProperty, as a DP can bind to any property without issue. As such, I'd revisit whether this is truly a bug in the control implementation first, and correct that.
However, if you must do this, realize you're going to violate MVVM - using DependencyObject within a ViewModel is, by its very nature, injecting view specific framework elements into the VM. Once you decide you're okay with doing this, you can always have your ViewModel expose a DependencyObject as a property, and bind to a DependencyProperty defined on that DependencyObject instead of directly to your VM's property.
I have a usercontrol with a command, what I would like to do is execute this command from the containing view's ViewModel.
This would be easy to accomplish in the code behind, as I could just go "UserControl.MyCommand.Execute", but of course I want to be able to do this in the ViewModel.
In theory, what I would like to do is bind the UserControl's Command to a Command on the ViewModel which I can execute and will then be handled by the UserControl. Something like this:
...
<local:MyControl
MyCommand="{Binding ViewModelsCommand}" />
...
Of course this will have the opposite affect to what I want to do, as now the ViewModelsCommand is bound to MyCommand. So how to invert this?
Basically I want to be able to bind something like this:
ViewModelsCommand="{Binding MyControl.MyCommand}"
Any ideas or inspiration would be welcomed, I can't see a binding Mode that would let me do this. And I'm not sure how to access the DataContext's properties for binding (usually you would do just bind and have twoway handle this, but of course that doesn't work in this scenario).
Thanks in advance.
You are instantiating the view-model in the constructor of the view.
Why not set the value explicitly upon construction?
public SomeView()
{
var viewModel = new SomeViewModel();
viewModel.ViewModelCommand = MyCommand; // or = myControl.MyCommand
DataContext = viewModel;
}
It is possible to use a binding with OneWayToSource, TwoWay, or Explicit, but you still have to explicitly update source at least once in code (always if you use Explicit).
myControl.GetBindingExpression(MyControl.MyCommandProperty).UpdateSource();
I use PRISM's EventAggregator, or MVVMLight's Messenger to allow two ViewModels to talk, but your case looks slightly different where you have a view(UserControl) talking to a ViewModel.
Please note, the following answer is not correct. It seems that OneWayToSource only updates after the target-property has changed. However I don't delete this answer to inform other people which are not aware of this behaviour (like me).
Old answer (see text above)
IMO your example should work (if MyControl.MyCommand is a public property that returns an ICommand). Have you tried the BindingMode OneWayToSource?
<local:MyControl
MyCommand="{Binding ViewModelsCommand,Mode=OneWayToSource}" />
I have been reading about MVVM pattern from various sources like MSDN:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
In that article it says: Unlike the Presenter in MVP, a ViewModel does not need a reference to a view.
If the View (XAML) assumes it's DataContext is the ViewModel then where in the code is the following line:
view.DataContext = viewModel;
The ViewModel doesn't know anything about the view so it cannot set the datacontext. If I give the ViewModel the reference do I break the MVVM pattern? My other choice is to have some kind of Builder or extra Presenter whose only job is to wire the whole thing (wait for the loaded event of the View, set the DataContext).
I know different view's can share the same DataContext (e.g. set the DataContext only for the mainwindow and others will see it) but in many cases that is not possible at all nor even feasible.
This is a great question that has many answers. It all depends on how you want to architect your application. For instance, I use dependency injection to create my IViewModel, which in turn creates my IView and my IViewModel runs an IView.SetViewModel(this) on the constructor.
Other people may wish to use a more Blendable method by setting the DataContext in the Xaml:
<UserControl.DataContext>
<ns:CrazyViewModel />
</UserControl.DataContext>
Sometimes the DataContext can be implied so it is set by the framework, like in the instance of a DataTemplate used by an ItemsControl. This is also pretty common in desktop WPF because it supports typed DataTemplates.
So there really isn't a wrong way to set the DataContext, just as long as what you have separates concerns, is maintainable and is also easily testable.
Shawn Wildermuth has a great post about whether the View or ViewModel comes first:
http://wildermuth.com/2009/05/22/Which_came_first_the_View_or_the_Model
I like, and use, his marriage concept where a 3rd party class creates both the view and viewmodel, and then associates the two. It's worked well for me.
I use MVVM a lot in with Prism. In Prism I use Unity for dependecy injection. Therefore I have an interface for every class registered with Unity including the View.
The IView interface has a method like this:
void SetViewModel(object viewModel);
The ViewModel calls this method at the end of its constructor, passing itself as a parameter:
public ViewModel(IView view, ...)
{
...
this._view=view;
this._view.SetViewModel(this);
}
In the View.xaml.cs the IView interface is implemented. This will be the only code I add to the codebehind of the view:
public partial class View:UserControl, IView
{
public View()
{
...
}
public SetViewModel(object viewModel)
{
this.DataContext = viewModel;
}
}
As for my own usage, the ViewModel doesn't know the View, or any interface on the View. And most of time, the View doesn't know its ViewModel, even if it is less important. The VM is just transprted by the DataContext.
This ensures that the VM and V will remain highly independant. Links are established thoughout bindings, commanding, Behaviors, Triggers & so on. Even if VM is often highly related to a given view, I try to make it as generic as possible, so that I can switch the corresponding View, and / or adapt the View behavior without needing to update the VM, except if the architectural link between V and M is impacted !
Let's have a button Command property bound to a custom command.
When should I implement ICommand and when derive from RoutedCommand? I see that RoutedCommand implements ICommand.
In which case could I need to implement an ICommand?
What about MVVM model? Which one suits better for this purpose?
As you have noticed the RoutedCommand class is an implementation of the ICommand interface, its main distinction if that its function is similar to that of a RoutedEvent:
The Execute and CanExecute methods on a RoutedCommand do not contain the application logic for the command as is the case with a typical ICommand, but rather, these methods raise events that traverse the element tree looking for an object with a CommandBinding. The event handlers attached to the CommandBinding contain the command logic.
The Execute method raises the PreviewExecuted and Executed events. The CanExecute method raises the PreviewCanExecute and CanExecute events.
In a case when you don't want the behavior of the RoutedCommand you'll be looking at your own implementation of ICommand. As for the MVVM pattern I can't say that one solution, it seems that everyone has their own methodology. However, here are a few approaches to this problem that I've come across:
Using RoutedCommands with a ViewModel in WPF
Relaying Command Logic
Simple Command (almost identical to Relay Command but worth reading)
The only thing I would add to Rich McGuire's answer is that RoutedCommands (and their more prevalent descendant RoutedUICommand have to be wired up with event handlers to work correctly.
Most MVVM implementations I have come across attempt to leverage binding against the ViewModel and thus the ViewModel (and not the View) owns the CanExecute/Execute logic.
In contrast, the event handlers move that burden to the View. The handling can then be propagated to the ViewModel, but this means a slightly higher degree of coupling between ViewModel and View (casting + method call, etc.).
I have begun creating a wpf mvvm app. It seems a vital ingredient to the ViewModel is a bunch of ICommands to have a loosely coupled way of allowing the view to interact with the viewmodel.
My question is this, why can't I bind directly to a method?
I have used Josh Smith's RelayCommand implementation of ICommand that allows you to inject delgates into an ICommand object, but really, is there some easier way to allow a button push to call a method in the viewmodel?
I'm new to MVVM, I believe I need some enlightenment
You can't bind directly to a method because Button (for example) doesn't have a property that accepts a delegate. Instead, it has a Command property of type ICommand. A RelayCommand (aka DelegateCommand) is just an ICommand that wraps delegates.
I see no technical reason why it wouldn't be possible for the view to bind to specific methods on the view model by way of a markup extension:
<Button Command="{ViewModelMethod SomeMethodName}"/>
However, this would be slower and would increase the coupling between the view and view model. If the view knows only about a property on the view model of type ICommand, the implementation of that command could change completely (or methods could be renamed) without the view being aware.
I completely disagree.
The speed of invocation bears no relevance: commands are user interactions, they never require speed.
Argument about coupling is flawed too. How come {Binding MyProperty} is not coupling but {ViewMethod MyMethod} is?
Requirement of having specially crafted 'Commands' to be wrapped around methods is a silly one. Commands might be useful implementation under the cover, but we already have methods in C# and replacing them with something big and bulky is not right.
And that thing about MarkupExtension and Binding, it really is difficult. But it can be done. Actually, it is done, you can have a look at MethodCall project on CodePlex:
http://methodcallthing.codeplex.com/
You can use binding to choose 'this' for the method, and can use binding to fetch arguments. And all those are live, i.e. being calculated at the time the command is invoked. Another bonus feature is push-out result of method call, you can use binding for that too (OneWayToSource).
ICommand gives you CanExecute, which is needed for control enabling. A simple delegate does not. ICommand is the way to go.
Apparently Microsoft needed a Command to be something first-class, probably because they felt having the CanExecute was necessary for most applications. I disagree and think the CanExecute should have just been another DependencyProperty that you would bind to a property of your viewmodel, but hey, what do I know?
Possibly they also thought that there was a need to decouple the implementation of a command from the control's datacontext. Yet again this seems unnecessary to me because the logic should live near the data that is being operated on, as is a fundamental principal of OO.
Personally I avoid using commands in MVVM because of the mess you have to create to implement them. I just let the view's code-behind delegate events up to the viewmodel.
Due to the way in which the title of this question is worded, readers might arrive here looking for an alternative to ICommand, instead of just a way to bind a UI action directly to a method of a viewModel. (Which is of little value, since it leaves open the question of what to do with the 'CanExecute` part.)
The use of ICommand is problematic in and of itself because it is defined in Windows.Input, which means that in order to declare ICommands in your ViewModels you have to reference WPF and the kitchen sink from within your application logic, and once you have done that, any noob might notice that MessageBox and a vast array of other GUI functionality is available, and might start making use of it, resulting in a terrible mess of mixed application logic and presentation logic.
So, if you want to get rid of using System.Windows, then you need to get rid of ICommand, and if you want to get rid of ICommand, then you might be happy to know the following:
WPF (specifically, the XAML designer) does not require your viewModels to statically expose instances of the ICommand interface.
By statically here I mean that the designer does not need to be able to prove, during design time, using reflection, that your command objects implement the ICommand interface; instead, WPF checks at runtime to make sure that UI actions are bound to objects which do in fact turn out to implement ICommand.
So, in your viewModels (application logic) instead of the ICommand interface of WPF you can be using some Command interface of your own device, and all you need to ensure is that the class that you will be instantiating at runtime to implement your Command interface also implements ICommand to keep WPF happy. This way you can avoid including ICommand from within your ViewModels, and subsequently you might be able to avoid having to reference System.Windows in your application logic.