Рассмотрим довольно классическую / простую конструкцию MVVM с элементами, которые отображаются с использованием Xaml-привязок к ViewModels для каждого элемента, соответственно. Элементы можно выбирать, а у ViewModels есть свойство IsSelected
, которое вызывает событие PropertyChanged
для свойства, относящегося к дизайну, например, BorderBrush
, чтобы пользовательский интерфейс мог правильно обновлять себя.
Необходимое взаимодействие с мышью осуществляется путем прослушивания событий туннелирования и всплытия родительского контейнера, оценки e.OriginalSource.DataContext
и, в конечном итоге, установки ViewModel.IsSelected
в одну или другую сторону.
Это работает нормально, если «относящиеся к дизайну» изменения могут обрабатываться только связанным элементом управления, но я хотел бы добавить Adorner
для каждого выбранного элемента / элемента управления и использовать его для выделения c пользовательских взаимодействий, например, select, move, размер. Это не проблема, если взаимодействие начинается и затрагивает только один из связанных с ViewModel элементов управления, потому что тогда элемент управления известен в области действия моего кода. Но если выбрано несколько элементов (например, с помощью команды «выбрать все»), как мне получить доступ к представлению / элементу управления всех затронутых моделей представления, чтобы я мог создать Adorner
для каждого элемента, который может использовать визуальные элементы целевого элемента управления, позиция или размер?
Я понимаю принцип MVVM (или намерение, стоящее за ним), что ViewModel не должен зависеть от View, но я не вижу другого пути и мне интересно, как лучше реализовать решение .
В настоящее время мой подход включает в себя что-то вроде этого:
public interface IViewModel{
FrameworkElement Element {get; set;}
}
public partial class MyItemControl : UserControl
{
public MyItemControl()
{
InitializeComponent();
this.DataContextChanged += OnDataContextChanged;
}
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
(e.NewValue as IViewModel)?.Element = this;
}
}
Есть ли другой способ, например, через привязки Xaml? Обычно я не предпочитаю чистые решения Xaml, но в этом случае это поможет мне избежать требований к элементам управления - или мне вообще потребуется использовать элементы управления.
И: действительно ли это нарушение упомянутого принципа?