Search code examples
c#wpfdata-bindingwpfdatagrid

How can I binding the SelectedItems property of a DataGrid in MVVM?


Well, I am using MVVM Light and I have tried the solution to pass as parameter the selectedItems of the datagrid in the event selectionChanged. So I can get the selecteditems and I can update my variable in the view model.

In a first moment, it is a good solution. The problem is that if I set in my view model the SelectedIndex property to -1 to deselect all or set to null the SelectedItem property, the event selectionChanged is not fired. I guess that really is it good, because why the view will notify to the view model the change of a property that is changed in a first moment in the view model? This does not create cycles, but then I need to clear my SelectedItems propery in my view model manually and notifiy and rise my event OnSelectionChanged to another view models changes in many parts of my code.

I would like to know how can I force to rise the selectionChagend event when I change the property in my view model. Perhaps the solution could be a attached property instead of using the event selectionChanged.

Which alternatives do I have?

Thank you.


Solution

  • Use RaisePropertyChanged in the setter of the selected item.

    private T _selectedItem;
    public T SelectedItem
    {
        get
        {
            return _selectedItem;
        }
        set
        {
            if(value != _selectedItem)
            {
                _selectedItem = value;
                RaisePropertyChanged("SelectedItem");
            }
        }
    }
    

    Or take a look at this one: INotifyPropertyChanged Is Obsolete and this one: Data Binding without INotifyPropertyChanged

    EDIT: Since 4.6 there's a more beautiful way:

    private T _selectedItem;
    public T SelectedItem
    {
        get
        {
            return _selectedItem;
        }
        set
        {
            if(value != _selectedItem)
            {
                _selectedItem = value;
                OnPropertyChanged();
            }
        }
    }
    
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        => RaisePropertyChanged(propertyName);
    

    CallerMemberName is for passing the Name of the calling member implicitly.