'Where should the Command and Command_CanExecute logic of my UserControl reside?
I have a view PeopleView that displays a list of People bound to a collection of People in PeopleViewModel.
In a panel within PeopleView I have a form (just a collection of text boxes and a button) which allows users to add a new person (People).
Initially I had this collection of controls as part of PeopleView but I want to separate it out into a separate UserControl (AddPerson) as it doesn't necessarily depend on the existing list of people and this AddPerson control could exist anywhere else in the application. I might want to reuse it elsewhere.
However, I'm struggling to work out where I should now be putting my button command and the associated CanExecute logic now.
It would have been in the PeopleViewModel but my AddPerson UserControl doesn't have a ViewModel. I've read that typically you wouldn't have a ViewModel for a UserControl, but I don't know how else I can make a reusable control that also contains its own business logic?
Should my AddPerson UserControl have a ViewModel, or should I be doing the business logic in the codebehind (seems very unlikely), or something else?
Solution 1:[1]
Commands traditionally go in the ViewModel but there's no hard fast rule on this. If you'd like to make a more reusable control, you can create a command dependency property on the control itself and then bind it to a command in your view model when the control is implemented.
This is identical to how button command is implemented
For example
MyUserControl.Xaml
<UserControl x:name="self">
<Grid>
<Button Command="{Binding ElementName=self, Path=MyDPCommand}"/>
</Grid>
</UserControl>
MyUserControl.Xaml.cs
public ICommand MyDPCommand
{
get { return (ICommand)GetValue(MyDPCommandProperty); }
set { SetValue(MyDPCommandProperty, value); }
}
public static readonly DependencyProperty MyDPCommandProperty =
DependencyProperty.Register(nameof(MyDPCommand), typeof(ICommand), typeof(MyUserControl), new PropertyMetadata(null));
And then in your implementation xaml you can bind it back to your viewmodel
MyView.Xaml
<MyUserControl MyDpCommand="{Binding MyViewModelCommand}"/>
Solution 2:[2]
In the end I've gone the route of implementing a ViewModel for my AddPerson view because, although it is technically a UserControl, I really am using it like any other view rather than a generic control.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Anthony Russell |
| Solution 2 | WSC |
