Example T142075
Visible to All Users

Use the EventToCommand Behavior to Execute Commands when an Event is Raised

The EventToCommand behavior allows you to bind an event to a command. When used, the bound command is invoked like an event handler when the event is raised.

In this example, the EventToCommand is used (to call an event) to display an edit form when a user clicks an item in the ListBox.

The code snippet below defines the EventToCommand that processes the ListBox's MouseDoubleClick event. When the event is raised, the EventToCommand invokes the bound EditCommand. This command requires a parameter: a Person object to be edited.

XAML
<UserControl x:Class="Example.View.MainView" ... xmlns:ViewModel="clr-namespace:Example.ViewModel" xmlns:Common="clr-namespace:Example.Common" xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" DataContext="{dxmvvm:ViewModelSource Type=ViewModel:MainViewModel}"> <Grid x:Name="LayoutRoot" Background="White"> <ListBox ItemsSource="{Binding Persons}"> <dxmvvm:Interaction.Behaviors> <dxmvvm:EventToCommand EventName="MouseDoubleClick" Command="{Binding EditCommand}"> <dxmvvm:EventToCommand.EventArgsConverter> <Common:ListBoxEventArgsConverter/> </dxmvvm:EventToCommand.EventArgsConverter> </dxmvvm:EventToCommand> </dxmvvm:Interaction.Behaviors> <ListBox.ItemTemplate> ... </ListBox.ItemTemplate> </ListBox> </Grid> </UserControl>

The code below illustrates an implementation of the EditCommand in both the Runtime POCO ViewModel and the common ViewModel.

C#
//POCO ViewModel [POCOViewModel] public class MainViewModel { public void Edit(Person person) { ... } public bool CanEdit(Person person) { return person != null; } } //Common ViewModel public class MainViewModel { public ICommand<Person> EditCommand { get; private set; } public MainViewModel() { EditCommand = new DelegateCommand<Person>(Edit, CanEdit); } public void Edit(Person person) { ... } public bool CanEdit(Person person) { return person != null; } }

In this specific instance, you must obtain the DataContext for the clicked ListBoxItem. This is what the EventToCommand should pass to the EditCommand as a parameter. This operation is performed by the custom ListBoxEventArgsConverter:

C#
using DevExpress.Mvvm.UI; using System.Linq; public class ListBoxEventArgsConverter : EventArgsConverterBase<MouseEventArgs> { protected override object Convert(object sender, MouseEventArgs args) { ListBox parentElement = (ListBox)sender; DependencyObject clickedElement = (DependencyObject)args.OriginalSource; ListBoxItem clickedListBoxItem = LayoutTreeHelper.GetVisualParents(child: clickedElement, stopNode: parentElement) .OfType<ListBoxItem>() .FirstOrDefault(); if(clickedListBoxItem != null) return (Person)clickedListBoxItem.DataContext; return null; } }

The ListBoxEventArgsConverter class inherits from the EventArgsConverterBase class and contains the Convert method. The EventToCommand uses this method to convert event arguments.

In this scenario, the EventToCommand passes a MouseEventArgs object to the ListBoxEventArgsConverter. The converter uses the LayoutTreeHelper class to locate the clicked ListBoxItem and then returns its DataContext (which contains the underlying Person object). The resulting Person object is then passed to the bound EditCommand.

Files to Look At

Documentation

Does this example address your development requirements/objectives?

(you will be redirected to DevExpress.com to submit your response)

Example Code

Common/MouseEventArgsConverter.cs(vb)
C#
using DevExpress.Mvvm.UI; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Linq; namespace Example.Common { public class ListBoxEventArgsConverter : EventArgsConverterBase<MouseEventArgs> { protected override object Convert(object sender, MouseEventArgs args) { var element = LayoutTreeHelper.GetVisualParents((DependencyObject)args.OriginalSource, (DependencyObject)sender).OfType<ListBoxItem>().FirstOrDefault(); return element != null ? element.DataContext : null; } } }
View/MainView.xaml
XAML
<UserControl x:Class="Example.View.MainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModel="clr-namespace:Example.ViewModel" xmlns:Common="clr-namespace:Example.Common" xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource Type=ViewModel:MainViewModel}"> <dxmvvm:Interaction.Behaviors> <dxmvvm:EventToCommand EventName="Loaded" Command="{Binding InitializeCommand}"/> <dx:DXMessageBoxService/> </dxmvvm:Interaction.Behaviors> <Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Text="Press Ctrl and click an item or select an item and press the Ctrl+Enter key combination."/> <ListBox x:Name="list" ItemsSource="{Binding Persons}" Grid.Row="1"> <dxmvvm:Interaction.Behaviors> <dxmvvm:EventToCommand EventName="MouseLeftButtonUp" Command="{Binding EditCommand}" ModifierKeys="Ctrl"> <dxmvvm:EventToCommand.EventArgsConverter> <Common:ListBoxEventArgsConverter/> </dxmvvm:EventToCommand.EventArgsConverter> </dxmvvm:EventToCommand> <dxmvvm:KeyToCommand Command="{Binding EditCommand}" KeyGesture="Ctrl+Enter" CommandParameter="{Binding ElementName=list, Path=SelectedItem}"/> </dxmvvm:Interaction.Behaviors> <ListBox.ItemTemplate> <DataTemplate> <TextBlock> <Run Text="{Binding FirstName}"/> <Run Text="{Binding LastName}"/> </TextBlock> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </UserControl>
ViewModel/MainViewModel.cs(vb)
C#
using DevExpress.Mvvm; using DevExpress.Mvvm.DataAnnotations; using DevExpress.Mvvm.POCO; using System.Collections.ObjectModel; namespace Example.ViewModel { [POCOViewModel] public class MainViewModel { public virtual ObservableCollection<Person> Persons { get; protected set; } protected virtual IMessageBoxService MessageBoxService { get { return null; } } public void Initialize() { Persons = new ObservableCollection<Person>(); Persons.Add(ViewModelSource.Create(() => new Person() { FirstName = "John", LastName = "Smith" })); Persons.Add(ViewModelSource.Create(() => new Person() { FirstName = "Alex", LastName = "Carter" })); } public void Edit(Person person) { MessageBoxService.Show(string.Format("{0} {1}", person.FirstName, person.LastName)); } public bool CanEdit(Person person) { return person != null; } } public class Person { public string FirstName { get; set; } public string LastName { get; set; } } }

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.