让我澄清一下你的理解:
是在后台代码一般是可以避免的,但仅仅是因为MVVM使得它很容易绑定到视图模型,以线了你的视觉元素与属性和命令场景是视图特定视图的代码隐藏
代码后面的功能是完全可以接受的假设它不穿过关注的边界。例如,我在我的应用程序中有一个对页面进行一些可视化处理的视图,为此我需要视图中有代码。此代码也可能与视图模型层交互,但它不会直接引用视图模型,因此保持我的组件松散耦合
如果您有需要特定方法调用的控件,则创建一个事件聚合器消息以将通知传播到视图是完全正确的,因为你仍然保持视图模型和视图之间的关注分离(并且应用程序组件保持封装和可测试)
示例视图(我已经将所有事件聚合器连接起来,代码和潜在的依赖注入东西出来的清晰度):
public class MyView : IHandle<SomeNotificationMessageType>
{
// Handler for event aggregator messages of type SomeNotificationMessageType
public void Handle(SomeNotificationMessageType message)
{
// Call a method on one of the page controls
SomePageControl.SomeMethod();
}
}
很显然,你不会做的是这样的视图模型:
public class MyViewModel : IViewAware
{
public void DoSomethingThatAffectsView()
{
var view = this.GetView() as MyView;
view.SomePageControl.SomeMethod();
}
}
违反了MVVM原则,因为你是紧密耦合MyViewModel和MyView的。
如果你想使用在卡利微它允许在同一视图模型的多个视图的Context
财产?上面的代码会中断 - 即使您检查了View类型,您仍然会得到意大利面代码,例如
public class MyViewModel : IViewAware
{
public void DoSomethingThatAffectsView()
{
var myview = this.GetView() as MyView;
if(myview != null)
myview.SomePageControl.SomeMethod();
var myotherview = this.GetView() as MyOtherView;
if(myotherview != null)
myotherview.SomePageControl.SomeMethod();
// ad infinitum...
}
}
当然,这是主观的:它可能是你的用户控件影响视图模型,并以复杂的方式的观点,在这种情况下,你可能要考虑寻找架构和工作指出,用户控件如何能更好地适合
你有什么背景知道UC是什么,它的方法是什么?
谢谢你的解释。我会用EventAggregator的想法去。我说的UC是AvalonDock,我想要做的是保存/加载布局。在版本1中*有一个SaveLayout()方法;现在从版本2开始。0显然必须将整个UC DockingManager传递给一个特殊的Serializer。 – PeterE
“为了清晰起见,所有......依赖注入的东西都被清除了”,现在还不清楚。 :)我能想到的唯一方法是获取Event Aggregator,在View的无参数构造函数中使用'IoC.Get()'。有没有更好的方法来注入依赖关系,而不是直接从容器中拉对象? –
您的视图也参与依赖注入 - 只需将其添加到构造函数即可。 – Charleh