0

I am trying to translate WPF CodeBehid events like Event, Handler, EventSetter to MVVM pattern. I am not allowed to use System.Windows.Controls since I am using MVVM. And I am also avoiding 3rd party library to solve this issue.

Can somebody explain how to convert the following CodeBehind Event Handler to MVVM Event-Handler? Please explain as much as you can while writing answer.

XAML Code

<DataGridCheckBoxColumn Header="Select" Binding="{Binding Path=IsSelected}"> 
  <DataGridCheckBoxColumn.CellStyle> 
    <Style TargetType="DataGridCell"> 
      <EventSetter Event="MouseLeftButtonUp" Handler="ApprovedMouseUp"></EventSetter> 
    </Style> 
  </DataGridCheckBoxColumn.CellStyle> 
</DataGridCheckBoxColumn> 

Code Behind

private void ApprovedMouseUp(object sender, MouseButtonEventArgs e) 
{ 
    if(sender is DataGridCell) 
    { 
        var temp = (sender as DataGridCell).Content; 
        if(temp is CheckBox) (temp as CheckBox).IsChecked = !(temp as CheckBox).IsChecked; 
    } 
} 
Shai
  • 529
  • 7
  • 20
  • 36

3 Answers3

1

You have a couple of choices:

  1. Attach the event handler in XAML but the only thing the event handler does is call into the view model passing in the appropriate arguments (it's important not to pass any GUI level items to the view model -- just the data necessary to perform the action)

  2. Use the EventToCommand behavior (showcased here) to attach an instance of an ICommand (from your view model) to an event in your view

As long as you're not trying to set these event handlers up in styles or templates I would recommend pursuing option #1 -- there is no iron law prohibiting you from using event handlers when convenient, as long as the view model is what actually performs all the work

Edit: Option #1

private void ApprovedMouseUp(object sender, MouseButtonEventArgs e) 
{ 
    if(sender is DataGridCell) 
    { 

        var checkBox= (sender as DataGridCell).Content as CheckBox; 
        if(checkBox != null) 
        {
            var viewModel = (MyViewModel)checkBox.DataContext;
            viewModel.ToggleApprovedStatus();
        }
    } 
} 
cordialgerm
  • 8,403
  • 5
  • 31
  • 47
  • I found I need use the following 3rd-party libraries to use EventToCommand. 1) GalaSoft.MvvmLight.dll, 2)GalaSoft.MvvmLight.Extras.dll besides System.Windows.Interactivity.dll. Since I am trying to avoid using third party library, can I have example for option-1? – Shai Oct 19 '11 at 18:43
  • How do i translate above Option#1 sample code to MVVM pattern? – Shai Oct 19 '11 at 20:27
  • @Shai that is the MVVM pattern. That event handler is in the code behind of the GUI and calls into the view model's ToggleApprovedStatus() method – cordialgerm Oct 19 '11 at 23:46
  • I am still having two issues. Issue #1: I still have to click twice, first click is selects cell and second click checks the check box. Issue #2: I am not understanding how would be implementation of MyViewModel reference to checkbox. – Shai Oct 20 '11 at 04:24
1

There are few thumb rules regarding MVVM....

  1. Your Models and ViewModles should not refer System.Windows.Controls namespace.
  2. Your Models and ViewModles should not handle events. Use ICommand interface for that.
  3. RoutedCommand is not valid in Models / ViewModels (due to point 2). Hence use DelegateCommand / RelayCommand

Having said that, all the above points are perfectly allowed if you have written an Attached Behavior in MVVM.

WPF-it
  • 19,625
  • 8
  • 55
  • 71
  • My biggest challenge is translating CodeBehind event to MVVM pattern. How do I convert Sender where I need to check whether if Sender is DataGrid? In the same way how do I verify whether it is checkbox or not? How do i hook Event, Handler? etc. Note: I am avoid 3rd party library to resolve this issue. – Shai Oct 19 '11 at 19:18
  • Hey Shai, Attached Behavior help you here. See my other post that does exactly that. In this exmaple I have handled an SelectionChanged() event of combobox to **cancel** selection upon specific conditions in MVVM ... http://stackoverflow.com/questions/7800032/cancel-combobox-selection-in-wpf-with-mvvm/7804972#7804972 – WPF-it Oct 20 '11 at 05:02
1

You can also use Caliburn Micro libraries to be able to attach a handler in ViewModel to an event in View.

Sample code:

 ...  xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro"....

 <Button Content="Edit" DataContext="{Binding Path=VmInstance}" 
             cal:Message.Attach="[Event Click] = [Action EditFilter]" />
Manish Basantani
  • 16,931
  • 22
  • 71
  • 103