DataGrid - изменить поведение редактирования - PullRequest
1 голос
/ 10 июля 2010

У меня есть ObservableCollection ChildViewModels с несколько сложным поведением.

Когда я иду на редактирование строки - DataGrid переходит в «режим редактирования» - это эффективно отключает UI-уведомления вне текущей ячейки, пока строка не будет зафиксирована - это предполагаемое поведение и, что более важно, его можно изменить?

Пример:

public class ViewModel
{
    public ViewModel()
    {
        Childs = new ObservableCollection<ChildViewModel> {new ChildViewModel()};
    }
    public ObservableCollection<ChildViewModel> Childs { get; private set; }
}
public class ChildViewModel : INotifyPropertyChanged
{
    private string _firstProperty;
    public string FirstProperty
    {
        get { return _firstProperty; }
        set
        {
            _firstProperty = value;
            _secondProperty = value;
            OnPropetyChanged("FirstProperty");
            OnPropetyChanged("SecondProperty");
        }
    }

    private string _secondProperty;
    public string SecondProperty
    {
        get { return _secondProperty; }
        set
        {
            _secondProperty = value;
            OnPropetyChanged("SecondProperty");
        }
    }

    private void OnPropetyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

И в поле зрения:

<Window.Resources>
    <local:ViewModel x:Key="Data"/>
</Window.Resources>
<DataGrid DataContext="{Binding Source={StaticResource Data}}" ItemsSource="{Binding Childs}"/>

Обратите внимание, как скрывается второе уведомление при редактировании первого столбца, пока вы не покинете строку.

РЕДАКТИРОВАТЬ: Реализация IEditableObject ничего не делает:

public class ChildViewModel : INotifyPropertyChanged,IEditableObject
{
    ...
    private ChildViewModel _localCopy;

    public void BeginEdit()
    {
        _localCopy = new ChildViewModel {FirstProperty = FirstProperty, SecondProperty = SecondProperty};
    }

    public void EndEdit()
    {
        _localCopy = null;
    }

    public void CancelEdit()
    {
        SecondProperty = _localCopy.SecondProperty;
        FirstProperty = _localCopy.FirstProperty;
    }
}

Ответы [ 3 ]

7 голосов
/ 13 июля 2010

Это поведение реализовано в DataGrid с использованием BindingGroup.DataGrid устанавливает ItemsControl.ItemBindingGroup, чтобы применить BindingGroup к каждой строке.Он инициализирует это в MeasureOverride, поэтому вы можете переопределить MeasureOverride и очистить их:

public class NoBindingGroupGrid
    : DataGrid
{
    protected override Size MeasureOverride(Size availableSize)
    {
        var desiredSize = base.MeasureOverride(availableSize);
        ClearBindingGroup();
        return desiredSize;
    }

    private void ClearBindingGroup()
    {
        // Clear ItemBindingGroup so it isn't applied to new rows
        ItemBindingGroup = null;
        // Clear BindingGroup on already created rows
        foreach (var item in Items)
        {
            var row = ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement;
            row.BindingGroup = null;
        }
    }
}
4 голосов
/ 17 августа 2015

Это очень старый вопрос, но существует гораздо лучшее решение, которое не требует создания подкласса DataGrid.Просто вызовите CommitEdit () в событии CellEditEnding:

bool manualCommit = false;

private void MyDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    if (!manualCommit)
    {
        manualCommit = true;
        MyDataGrid.CommitEdit(DataGridEditingUnit.Row, true);
        manualCommit = false;
    }
}
0 голосов
/ 10 июля 2010

хорошо, вот в чем проблема. Observable Collection НЕ уведомляет об изменениях объектов, которые она содержит. Он только уведомляет о добавлении / удалении / и т.д. операции, которые обновляют коллекцию is-self.

У меня была эта проблема, и мне пришлось вручную добавить мои столбцы в сетку данных, а затем установить элемент Binding для объекта Column. чтобы оно связывалось с моим содержимым.

Кроме того, я сделал объекты, которые в моем ICollectionView, получены из IEditableObject, поэтому при их "обновлении" сетка обновится сама.

это отстой, но это то, что я должен был сделать, чтобы заставить его работать.

При желании вы можете создать собственную ObservableCollection, которая присоединяет / отсоединяет обработчики измененных свойств при добавлении и удалении элемента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...