-2

I'm required to fire a command on the click of an item of my ListView. The Event is present in the ViewModel and should not be implemented in the code behind.

I'm currently handling it by using an EventSetter with the command being in the code behind, but I need it in ViewModel.

In short, I want to change the values of property1 and property2 (present in the ViewModel) as soon as I click on a item of the list. Please help?

XAML:

 <ListView.ItemContainerStyle>
        <Style TargetType= "ListViewItem">
           <EventSetter Event="PreviewMouseLeftButtonDown" Handler="MyCommand"/>
        </Style>
    </ListView.ItemContainerStyle>

CODE BEHIND:

private voide MyCommand(object sender, MouseButtonEventArgs e)
{
    ViewModel.property1 = true;
    ViewModel.property2 = false;
}
Bella Swan
  • 153
  • 10
  • Have a look at existing [thread](https://stackoverflow.com/questions/12422945/how-to-bind-wpf-button-to-a-command-in-viewmodelbase) and don't forget to create your VM – Pavel Anikhouski Oct 22 '19 at 11:47
  • 1
    Just to clarify, that command is not supposed to implement the selection of an item? – Clemens Oct 22 '19 at 11:49
  • as Clemens wrote ... why don't you use SelectedItem of ListView ? – Selvin Oct 22 '19 at 11:49
  • @Clemens I need to set the value of some properties as soon as the item is clicked, so I'm using the command to do that. – Bella Swan Oct 22 '19 at 11:50
  • @Selvin I'm trying but am failing. Could you kindly explain with an example? – Bella Swan Oct 22 '19 at 11:51
  • `..SelectedItem="{Bind SelectedItem}"..` then in VM `...SelectedItem { set { /* do the stuff here*/ } }..` – Selvin Oct 22 '19 at 11:52
  • @Selvin how can I bind the function/command with the selected item so that it fires as soon as the item is clicked? – Bella Swan Oct 22 '19 at 12:00
  • @BellaSwan By default, a click on a ListView item selects it, however a second click does not automatically deselect it. Click and select are different things. ListView has a SelectedItem property that can be bound to a view model property. Is that what you need or not? Don't let us guess all this. Tell us precisely what you are trying to achieve. Do you perhaps just want to mark the associated view model item as selected? – Clemens Oct 22 '19 at 12:05
  • @Clemens I'm sorry if I'm not being clear. All I need is that as soon as I select a ListView item, the compiler goes into a FUNCTION/ EVENT that is present in the view model. Like the one I've used in code behind in my question, but it now has to be in view model. How can I achieve that? – Bella Swan Oct 22 '19 at 12:12
  • Set your `DataContext = new YourViewModel();` Set `SelectedItem` like Selvin explain... there you go – Nawed Nabi Zada Oct 22 '19 at 12:17
  • @NawedNabiZada SelectedItem can be bound to a property, not a function. I need a function to be fired as soon as the item is clicked. – Bella Swan Oct 22 '19 at 12:18

1 Answers1

2

Your view model item should have a boolean property that indicates if it is selected or not. Any code that needs to be executed when the selection state of an item changes can be called in the property setter.

public class ViewModelItem : INotifyPropertyChanged
{
    private bool selected;

    public bool Selected
    {
        get { return selected; }
        set
        {
            selected = value;
            // fire PropertyChanged event
            // add call optional additional code here
        }
    }
}

You would bind the IsSelected property of a ListViewItem to that property in the ItemContainerStyle:

<ListView.ItemContainerStyle>
    <Style TargetType= "ListViewItem">
        <Setter Property="IsSelected" Value="{Binding Selected}"/>
    </Style>
</ListView.ItemContainerStyle>

In case you have a single-selection ListView, and only need to get notified when the single selected item changes, add an appropriate property to you main view model, and call your code in its setter:

public class ViewModel : INotifyPropertyChanged
{
    public ObservableCollection<ViewModelItem> Items { get; }
        = new ObservableCollection<ViewModelItem>();

    private ViewModelItem selectedItem;

    public ViewModelItem SelectedItem
    {
        get { return selectedItem; }
        set
        {
            selectedItem = value;
            // fire PropertyChanged event
            // add call optional additional code here
        }
    }
}

Bind the ListView's SelectedItem like this:

<ListView ItemsSource="{Binding Items}"
          SelectedItem="{Binding SelectedItem}" />
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • 4
    Ok, what is this going to tell us? We do not know anything about your view model, so how are we supposed to proceed? – Clemens Oct 22 '19 at 12:42