Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF DataGrid SelectedItem binding stops working after item change

Tags:

c#

mvvm

wpf

xaml

My problem/situation is very similar to Wpf DataGrid SelectedItem loses binding after cell edit but I'm not using any "custom" WPF framework. I have a model that implements INotifyPropertyChanged and IEditableObject, and a grid bound to an ObservableCollection<T>. The grid's SelectedItem property is bound to a property on the VM.

With a break point, I can see my ViewModel.SelectedItem property change as I select different rows in the grid. The moment I change a value on a row, however, the ViewModel.SelectedItem property is no longer set as I change focus on the rows. The solution identified in the above link does not work since I'm not using a custom WPF framework, just naked WPF.

Any ideas?

// View model area
public IPurchaseorderItem SelectedItem
{
    get 
    { 
        return _selectedItem;
    }

    set
    {
        if (_selectedItem != value)
        {
            _selectedItem = value;
            SelectItemCommand.NotifyCanExecuteChanged();
            RemoveItemCommand.NotifyCanExecuteChanged();
        }
    }
}

// XAML SelectedItem binding
<views:NoBindingGroupDataGrid SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  

// Special Grid to clear binding groups (read on a similarly themed SO question/answer)
internal sealed class NoBindingGroupDataGrid : DataGrid
{
    private bool _editing = false;

    protected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize)
    {
        var desiredSize = base.MeasureOverride(availableSize);
        ClearBindingGroup();
        return desiredSize;
    }

    protected override void OnCellEditEnding(DataGridCellEditEndingEventArgs e)
    {
        base.OnCellEditEnding(e);

        if (!_editing)
        {
            _editing = true;

            CommitEdit(DataGridEditingUnit.Row, true);

            _editing = false;
        }
    }

    private void ClearBindingGroup()
    {
        ItemBindingGroup = null;

        foreach (var item in Items)
        {
            var row = ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement;

            if (row != null)
            {
                row.BindingGroup = null;
            }
        }
    }
}
like image 799
Martin Bliss Avatar asked Jun 26 '13 00:06

Martin Bliss


1 Answers

Apparently the SelectedItem dependency property on DataGrid is broken and not being used correctly. After some debugging using OnPropertyChanged, I found that the grid is actually setting a "CurrentItem" property reliably. I changed to use CurrentItem instead and everything appears to work correctly... the user's "selected row" is being sent to the VM without incident.

like image 199
Martin Bliss Avatar answered Oct 14 '22 04:10

Martin Bliss