Note that there are some explanatory texts on larger screens.

plurals
  1. PODouble Click on a WPF ListView - how to fire a command and not use an event handler
    primarykey
    data
    text
    <p>I am a little confused on how to implement an event as a command in my particular situation. I want to honour MVVM, but don't get how in this case.</p> <p>I have a WPF 'view' - viewCustomerSearch. This has some text boxes on it, and when the user clicks 'Search' the results are populated in ListView. viewCustomerSearch is bound to viewmodelCustomerSearch, and it works great.</p> <p>viewCustomerSearch is hosted on viewCustomer.</p> <p>I want to know have viewCustomerSearch expose a custom command - CustomerSelectedCommand - that is 'fired' whenever the ListView in viesCustomerSearch is double clicked, and then handled by the viewmodel behind viewCustomer (which is viewmodelCustomer). This seems the theoretical MVVM pattern implemented correctly.</p> <p>I have broken down the main problem into three smaller problems, but hopefully you can see they are all components of the same challenge.</p> <p><strong>FIRST PROBLEM</strong>: in order to have viewCustomerSearch expose a custom command I seem to have to put this code in viewCustomerSearch - which seems to 'break' MVVM (no code in the view code behind).</p> <pre><code>public readonly DependencyProperty CustomerSelectedCommandProperty = DependencyProperty.Register("CustomerSelectedCommand", typeof(ICommand), typeof(viewCustomerSearch)); public ICommand CustomerSelectedCommand { get { return (ICommand)GetValue(CustomerSelectedCommandProperty); } set { SetValue(CustomerSelectedCommandProperty, value); } } </code></pre> <p><strong>SECOND PROBLEM</strong> (and this is the one that is really getting to me): Best explained by showing what I would do which breaks MVVM. I would have an event handler in the view:</p> <pre><code>private void lstResults_MouseDoubleClick(object sender, MouseButtonEventArgs e) { if (CustomerSelectedCommand != null) CustomerSelectedCommand.Execute(((ViewModels.viewmodelCustomerSearchResult)this.lstResults.SelectedItem).CustomerId); } </code></pre> <p>Well ... I know that you shouldn't put this event handler here; rather it should have a Command to handle it in the viewmodelCustomerSearch. The two problems here are</p> <ul> <li><p>because the 'CustomerSelectedCommand' ICommand is implemented in viewCustomerSearch, viewmodelCustomerSearch can't see it to fire it.</p></li> <li><p>I cannot see how to bind the MouseDoubleClick event to a command, instead of an event handler in the view code behind. I am reading about Attached Properties, but cannot see how they are to be applied here.</p></li> </ul> <p>(Please note: I am using the common 'RelayCommand' elsewhere in the application; does this come into play here??)</p> <p><strong>THIRD PROBLEM</strong>: When I do use the non-MVVM way of firing the command in the code behind event handler, you can see that I am passing in the Selected Customer Id as an arguement into the command. How do I see that argument in the Command handler in viewCustomer? I create a new RelayCommand to handle it, but it seems the Execute method does not take arguments?</p> <p>Given all of the above, I have to say that I do NOT personally subscribe to the 'MVVM means NO CODE IN THE VIEW'. That seems crazy to me; code that is entirely to do with the view, and the view only, should not - IMHO - go in the viewmodel. That said, though, this does seem like logic-y stuff (not view stuff).</p> <p>Many thanks for some insight. Sorry for the long post; trying to balance enough information for you to help me with 'War and Peace'.</p> <p>DS</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload