Имеется класс Action, который представляет собой некое действие. Это действие также может содержать коллекцию вложенных действий ChildAction.
public class Action
{
public Action Parent {get;set;}
public ObservableCollection
Класс ProjectVM представляет собой коллекцию действий Action
public class ProjectVM : BaseVM
{
public ObservableCollection
В 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
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,
//если да, то выполняем нужные действия
}
}
Комментариев нет:
Отправить комментарий