Страницы

Поиск по вопросам

понедельник, 8 июля 2019 г.

Чтение VM-свойства за пределами VM

Имеется класс Action, который представляет собой некое действие. Это действие также может содержать коллекцию вложенных действий ChildAction.
public class Action { public Action Parent {get;set;} public ObservableCollection ChildActions {get;set;} }
Класс ProjectVM представляет собой коллекцию действий Action
public class ProjectVM : BaseVM { public ObservableCollection Actions {get;set;} }
В MainVM есть свойство, которое хранит активный проект:
public class MainVM : BaseVM { public ProjectVM SelectedProject{get;set;} }
В интерфейсной части ProjectVM представлен TreeView, а коллекция Actions его элементами, которые можно перетаскивать и вкладывать друг в друга.
Drag&Drop реализован с помощью GongSolutions.Wpf.DragDrop.
Мне нужно знать какой элемент куда был перенесен для формирования истории изменений (Undo/Redo) в каждом ProjectVM
Но как в обработчиках Drag&Drop подцепиться к SelectedProject в рамках MVVM, которые находятся вне всей этой экосистемы и просто цепляются к контролам с помощью attached property?


public class DropHandler : IDropTarget { //... public void Drop(IDropInfo dropInfo) { //Здесь нужно взаимодействие с SelectedProject } }
Можно, конечно, сделать свойство SelectedProject статическим, но что-то мне подсказывает, что это неправильно.
Может быть это вообще неправильный подход?


Ответ

Воспользуйтесь мессенджером для передачи сообщений (читай - инициирование событий) между Вашими VM. В коде обработчика drop - вызываете событие, в нужной Вам модели это событие обрабатываете и сохраняете историю действий. Для этой цели можете воспользоваться event broker. Очень удобное API, позволит Вам обеспечить низкий уровень связности между классами приложения.
public class DropInfoEventArgs : EventArgs { public IDropInfo DropInfo { get; private set; }
public DropInfoEventArgs(IDropInfo dropInfo) { this.DropInfo = dropInfo; } }
public class MainVM { private EventBroker broker; private List dropPublishers;
public MainVM() { this.broker = new EventBroker(); this.dropPublishers = new List();
var dropPublisher = new DropHandler(); this.dropPublishers.Add(dropPublisher);
this.dropPublishers.ForEach(dp => this.broker.Register(dp)); } }
public class DropHandler : IDropTarget { [EventPublication("topic://ProjectVM/HasBeenDropped")] public event EventHandler DroppedEvent;
public void Drop(IDropInfo dropInfo) { DroppedEvent(this, new DropInfoEventArgs(dropInfo)); } }
public class ProjectVM { [EventSubscription("topic://ProjectVM/HasBeenDropped", typeof(OnPublisher))] public void DroppedEvent(object sender, DropInfoEventArgs e) { DropHandler eventSource = sender as DropHandler; IDropInfo info = e.DropInfo; //определяем, относится ли это события к нашему ProjectVM, //если да, то выполняем нужные действия } }

Комментариев нет:

Отправить комментарий