
[英]WPF/MVVM : How to bind model to view/viewmodel from ItemsControl
[英]WPF/MVVM: How to reference the View from the ViewModel
考虑一个相当经典/简单的 MVVM 构造,其中的项目分别使用 Xaml 绑定到 ViewModel 来显示每个项目。 这些项目是可选择的,并且 ViewModel 有一个IsSelected
属性,该PropertyChanged
为与设计相关的属性(例如BorderBrush
引发PropertyChanged
事件,以便 UI 可以正确更新自身。
所需的鼠标交互是通过侦听父容器的隧道和冒泡事件、评估e.OriginalSource.DataContext
并最终以一种或另一种方式设置ViewModel.IsSelected
来完成的。
这工作正常,如果“设计相关”更改可以由绑定控件单独处理,但我想为每个选定的项目/控件添加一个Adorner
,并使用它来突出显示特定的用户交互,例如选择、移动、调整大小. 这不是问题,如果交互开始并且只影响 ViewModel 绑定的控件之一,因为然后该控件在我的代码范围内是已知的。 但是,如果选择了多个项目(例如,通过“全选”命令),所有受影响的ViewModels的,我怎么访问View /控制,这样我可以创建一个Adorner
为每一个可以使用目标控制的视觉效果,位置或尺寸?
我理解 MVVM 原则(或其背后的意图),即 ViewModel 不应依赖于视图,但我没有看到任何其他方式,并且想知道如何最好地实现解决方案。
目前我的方法将包括这样的事情:
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 解决方案,但在这种情况下,它会帮助我避免对控件的要求 - 或者我根本不需要使用控件。
并且:这是否确实违反了上述原则?
视图模型永远不应该直接访问视图。 没有例外。 在过去的 15 年里,我开发了一些极具挑战性的 WPF 应用程序,我从来没有遇到过不打破这一基本规则就无法优雅解决的案例。
要回答您的问题,有几种方法可以做到这一点,尽管您选择哪种实现方式取决于您的情况。 最简单的方法之一是使用行为。 您为该行为提供了一些依赖属性,您将这些属性绑定到视图模型中的 INPC 属性,并在那里编写代码以相应地创建/更新您的装饰器。
请记住,行为实际上只是代码隐藏的另一种形式,尽管稍微抽象一些。 许多人陷入使用行为和转换器来实现功能的陷阱,这些功能可以通过 DataTriggers 之类的东西轻松实现。 同样,具体细节将取决于您想要做什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.