Search code examples
wpfxamlmvvmprismmef

Calling a command from item collection in PRISM/ MEF/ WPF


Suppose I have the following:

<Grid x:Name="root">
    <ListBox ItemsSource="{Binding Path=Items}">
        <ListBox.ItemTemplate>
            <DataTemplate>
             <DockPanel>
               <Button Command="{Binding ElementName=root, Path=DataContext.MyCommand}" />
               <!---There are other UI elements here -->
              </DockPanel/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

This code executes MyCommand when the button is clicked, but I also want to execute MyCommand when the user presses Enter Key while the row is selected (which means button is not in focus)...

How to best do this in WPF/MEF/PRISM?

I recognize that in code I can't cast the DataContext to (MyViewModel) because that would violate MEF, and in code behind I only know the viewmodel interface type IViewModel...

//code behind of the XAML file above
public IViewModel ViewModel
{
    get;
    set;
}

Note: I am thinking of doing this in code behind, but I'm not sure if the answer is even I should do it in the viewmodel...


Solution

  • This can be done using KeyBindings. Create a new KeyBidnign to your Window and associate a Command to it. More information on KeyBindings.

    <ListBox.InputBindings>
        <KeyBinding Key="Enter" Command="{Binding MyCommand}"/>
    </ListBox.InputBindings>
    

    The CanExecute method of your viewmodel should have a validation for Selected Row.

    public class ViewModel
    {
        public ViewModel()
        {
            MyCommand = new DelegateCommand(MyCommandExecute, MyCommandCanExecute);
        }
    
        private void MyCommandExecute()
        {
            // Do your logic
        }
    
        private bool MyCommandCanExecute()
        {
            return this.SelectedRow != null;
        }
    
        public object SelectedRow { get; set; }
    
        public DelegateCommand MyCommand { get; set; }
    }