The answer is a dependency property. I had the same problem. First, if you do not have a DataTemplate, the solution is straightforward:
(this.Content as FrameworkElement).DataContext = this;
You set the DataContext UserControl in your constructor by your code.
If you are planning your team for us inside a DataTemplate, you will need DependecyProperty.
Example:
<DataTemplate> <Button Command="{Binding DataContext.MyCommand, ElementName=ParentName}"> </DataTemplate>
And to back it up, you create a dependency property for this command:
public ICommand MyCommand { get { return (ICommand)GetValue(MyCommandProperty); } set { SetValue(MyCommandProperty, value); } }
So, now when you use your custom control, it will have the MyCommand property on it, which you can bind to any command from the ViewModel if the template parent matches the one you provided, and also the parameter is bound to the actual element that the control is part.
<usercontrols:button MyCommand="{Binding MyCommandFromViewModel}" CommandParameter="{Binding}"/>
A simple example:
UserControl Code for
public sealed partial class ListviewUserControl : UserControl { public ListviewUserControl() { this.InitializeComponent(); (this.Content as FrameworkElement).DataContext = this; } public ICommand ButtonCommand { get { return (ICommand)GetValue(ButtonCommandProperty); } set { SetValue(ButtonCommandProperty, value); } }
UserControl Xaml:
<Grid> <ListView ItemsSource="{Binding ItemSource}" x:Name="ListView"> <ListView.ItemTemplate> <DataTemplate> <AppBarButton Icon="Delete" Command="{Binding ButtonCommand, ElementName=ListView}" CommandParameter="{Binding}"/> </DataTemplate> </ListView.ItemTemplate> </ListView> </Grid>
Usage in Page.xaml:
<Controls:ListviewUserControl ItemsSource="{Binding ViewModelsItemsList}" ButtonCommand="{Binding ViewModelsCommand}"/>