Где обновить наблюдаемые WPF? - PullRequest
0 голосов
/ 22 мая 2018

Рассмотрим случай, когда у меня есть приложение WPF с StudentView, которое привязывается к свойству (ObservableCollection) в StudentViewModel.У меня также есть StudentService, который получает зависимость от моего StudentRepository.StudentService предоставляет CRUD-операции, которые вызываются из других контекстов, отличных от пользовательского интерфейса.

Моя первая реализация имеет ObservableCollection в StudentService.Несмотря на то, что он работает с асинхронным вызовом и всеми остальными, эта установка во многих отношениях сопротивляется и не выглядит правильно.Особенно при обновлении ObservableCollection из различных контекстов.

Так что я думаю, что лучшим подходом было бы сохранить Observables на уровне представления (View / ViewModel) и сделать так, чтобы StudentViewModel подписывался на события из StudentService, а затемобновить Observables в контексте, в котором они находятся.

Так что мой вопрос в том, является ли мой пересмотренный подход лучше или, возможно, есть третий вариант, который даже лучше?

РЕДАКТИРОВАТЬ с примерами:

В настоящее время у меня есть это (упрощенно, но с важными вещами, я думаю):

Представление показывает список студентов, источник данных - моя ViewModel:

ItemsControl ItemsSource="{Binding Students.Result, UpdateSourceTrigger=PropertyChanged}">..</ItemsControl>

ViewModel:

public class MainViewModel : ViewModelBase
{
   public NotifyTaskCompletion<AsyncObservableCollection<Student>> Students { get; private set; }

   public MainViewModel(IStudentService service)
   {
      Students = new NotifyTaskCompletion<AsyncObservableCollection<Student>>(service.List());
   }
}

Компонент NotifyTaskCompletion взят из статьи Стивена Клири здесь .И AsyncObservableCollection извлекается из здесь .

Мой StudentService имеет такой интерфейс:

public interface IStudentService
{
   Task<bool> Add(Student student);
   Task<AsyncObservableCollection<Student>> List();
}

IStudentService.Add (...) вызывается из фоновых потоков, и это должно быть обнаружено в пользовательском интерфейсе.

Теперь все это работает, но есть некоторые проблемы с блокировкой (я думаю) AsyncObservableCollection.Поэтому я думаю, что мне нужна блокировка из контекста пользовательского интерфейса, но тогда это кажется неправильным - необходимость ссылаться на пользовательский интерфейс в моем сервисе.И я собираюсь вытащить AsyncObservableCollection (которая является ObservableCollection) и просто вернуть Task<IEnumerable<Student>> из моего сервиса - и вместо этого запустить некоторые события "OnStudentAdded" из сервиса ...

Надеюсьэто делает это более ясным?

Спасибо.

1 Ответ

0 голосов
/ 22 мая 2018

Служба должна каким-то образом уведомлять модель представления при каждом добавлении или удалении новых элементов.Я согласен с тем, что лучше сделать это, либо вызывая события из класса обслуживания, либо выставляя IObservable<T>, на который может подписаться модель представления.

Если вы выставляете публичное свойство ObservableCollection<T> из службык которому привязано представление, вы не сможете обновить эту коллекцию из фонового потока в классе обслуживания.Служба в некоторой степени зависит от клиента.

Привязка напрямую к свойствам, предоставляемым классом службы, редко является хорошей идеей.Вы можете создать копию коллекции в модели представления и привязать ее к этой, но тогда вам все равно нужно синхронизировать эту коллекцию с той, что определена в службе, и это не проще, чем подписка на событие или IObservable<T>и обновите коллекцию источников данных с привязкой «вручную» в модели представления.

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