2013-10-31 49 views
2

我正在使用Caliburn.Micro编写ViewModel-first MVVM应用程序 我的视图包含第三方UserControl,它实现了我想要/需要从关联的ViewModel调用的方法。我如何做到这一点,同时仍然支持MVVM原则?从Caliburn.Micro的ViewModel中调用UserControl方法

存在一个老thread这里那么,类似的问题被问更具体的上下文。如果有人能够充实那里提出的方法,我将不胜感激。

方法的一个建议,查看可以订阅的IEventAggregator消息。但是,我不需要使用文件后面的代码来做到这一点吗? (我认为这是一个很大的不,不以MVVM)

关于方法有两个,我不知道该怎么做。关于方法三,这就是我先尝试的,但不知何故,我没有完全实现它。

回答

5

让我澄清一下你的理解:

是在后台代码一般是可以避免的,但仅仅是因为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是什么,它的方法是什么?

+0

谢谢你的解释。我会用EventAggregator的想法去。我说的UC是AvalonDock,我想要做的是保存/加载布局。在版本1中*有一个SaveLayout()方法;现在从版本2开始。0显然必须将整个UC DockingManager传递给一个特殊的Serializer。 – PeterE

+0

“为了清晰起见,所有......依赖注入的东西都被清除了”,现在还不清楚。 :)我能想到的唯一方法是获取Event Aggregator,在View的无参数构造函数中使用'IoC.Get ()'。有没有更好的方法来注入依赖关系,而不是直接从容器中拉对象? –

+0

您的视图也参与依赖注入 - 只需将其添加到构造函数即可。 – Charleh

相关问题