WPF DataGrid: чистая обработка CanUserAddRows = true с помощью MVVM - PullRequest
1 голос
/ 05 ноября 2010

Я в последнее время изучал MVVM, и после того, как я обнаружил Caliburn.Micro , все было довольно хорошо;Я все еще на начальных этапах обучения, но я верю, что у меня хорошее представление об основах MVVM.

Однако я сталкиваюсь с проблемами с WPF DataGrid - и это в значительной степени те же проблемы , что и у меня с WinForms DataGridView: как, черт возьми, вы справляетесь с CanUserAddRows=true чистым добавлением элементов в сетку?

Я явно не хочу добавлять DataGrid -специфичныевзломает мою ViewModel, так как он в идеале должен быть пригоден для других View элементов управления.В то же время я хотел бы получить уведомление о добавлении нового элемента row , поэтому я могу сохранить его сразу.

Я связываюDataGrid до BindableCollection<FooModel> FooItems - с чистым дизайном MVVM, если я правильно понимаю вещи, я смогу обработать FooItems.CollectionChanged и реагировать на события Add / Remove.Однако DataGrid запускает событие Add, как только добавляется созданный по умолчанию элемент - это, очевидно, не правильное время для сохранения объекта!

После большого количества поиска в Googleи копаясь в StackOverflow, у меня складывается впечатление, что DataGrid крайне тормозится при запуске событий Add / Remove.Люди, которые используют его с CanUserAddRows=true, похоже, работают только с коллекциями в памяти, где люди, которые сохраняют данные, используют отдельные поля ввода + кнопки Команды для добавления новых элементов.

MyFooModel реализует INotifyPropertyChanged, но не IEditableObject - насколько я могу судить, это не должно быть проблемой, так как IEO, похоже, связан со свойством edit / undo, в то время как моя проблема в том, когда происходит событие Add...

Итак, что вы делаете для обработки редактирования в сетке чисто ?

Ответы [ 2 ]

2 голосов
/ 05 ноября 2010

Похоже, что WPF DataGrid ведет себя так же, как WinForms DataGridView, в том смысле, что он создает элемент в источнике данных, как только пользователь начинает входить в «новую строку».Последующее редактирование приведет к изменениям свойств нового элемента в коллекции.

Если вместо этого вы будете использовать BindingList<FooModel>, вы получите дополнительное событие, называемое ListChanged - предоставляя ваши средства типа FooModelINotifyPropertyChanged, событие будет срабатывать при изменении свойств элемента (а также при добавлении / удалении элементов из коллекции).

Надеюсь, это поможет!

0 голосов
/ 09 апреля 2013

Я знаю, что прошло много времени с тех пор, как об этом спросили, но сейчас я работаю над чем-то похожим и думал, что опубликую свое решение.Вы можете считать это хаком, но это лучший способ, с помощью которого я мог бы заставить DataGrid сообщать мне, когда он вышел из режима редактирования (по моим собственным причинам).

Я просмотрел код DataGrid и нашел ближайшийвещь, чтобы закончить редактирование, я мог бы переопределить, который оказывается OnExecutedCommitEdit ().Затем я просто вызываю событие после завершения этой функции.Когда мой подписчик на событие вызывается, DataGrid больше не находится в режиме редактирования, и я могу делать с ним все, что мне нужно.Вот код:

/// <summary>
/// Deriving a new DataGrid because we need an event to tell us when editing is complete.
/// </summary>
public class DataGridMod : DataGrid
{
   public delegate void EditCompletedDelegate();
   public EditCompletedDelegate EditCompleted;

   public DataGridMod() { }

   protected override void OnExecutedCommitEdit(ExecutedRoutedEventArgs e)
   {
      base.OnExecutedCommitEdit(e);

      if (EditCompleted != null)
         EditCompleted();
   }
}
...