Хочу прокомментировать ответ Денниса Роша.Действительно, в этом случае мы можем использовать подход с переносом, потому что нам нужно перерисовать представление, когда коллекция Shapes изменилась.Но логика модели представления может быть слишком сложной, и, например, вместо перерисовки в PropertyChanged мы должны перерисовать какое-то пользовательское событие (например, ModelReloadEvent).В этом случае перенос не помогает, но подписка на это событие помогает, как в решении Muad'Dib - модель представления использует связь на основе событий с представлением, но это событие должно быть специфичным для представления.
Использование кодаЗадняя с View специфическая логика не нарушает MVVM.Да, этот код может быть украшен поведением / действием, но использование кода позади - просто простое решение.
Кроме того, взгляните на это представление MVVM .Согласно структуре, ViewModel знает об абстрактном IView.Если вы работали с платформами Caliburn / Caliburn.Micro MVVM, вы помните класс ViewAware и IViewAware, который позволяет получить представление в модели представления.
Итак, более гибкое решение, я думаюследующее:
Просмотр:
public class CanvasView() : ICanvasView
{
public CanvasView()
{
InitializeComponent();
}
public void DrawShapes()
{
// implementation
}
}
ICanvasView:
public interface ICanvasView
{
void DrawShapes();
}
CanvasViewModel:
public class CanvasViewModel : ViewAware
{
private ObservableCollection<IShape> _shapes;
public ObservableCollection<IShape> Shapes
{
get
{
return _shapes;
}
set
{
_shapes = value;
NotifyOfPropertyChange(() => Shapes);
RedrawView();
}
}
private void RedrawView()
{
ICanvasView abstractView = (ICanvasView)GetView();
abstractView.DrawShapes();
}
}