2013-01-09 110 views
28

我有一个WPF窗口,并在该窗口中有一个网格。如何在viewmodel中访问mvvm模型中的控件?

我用M-V-VM模型,我想一个文本框在代码中动态添加到网格(在视图模型)

我怎样才能接入电网?

+3

在走下这条路线之前,我会确保它绝对必要,通常是从视图模型访问视图的不良做法,除非绝对没有其他选择。 – BenjaminPaul

+1

本杰明保罗说了些什么。使用MVVM时,您不会从ViewModel添加控件。使用绑定来完成这件事。 –

+2

是的,我知道这一点,正是我的意思。然而,我有时需要参考视图模型中的控件来迎合不支持常规绑定的控件。那就是我所指的场景。 – BenjaminPaul

回答

60

使用监督控制器模式。

阅读:

例实施如下所示CaliburnMicro MVVM框架(将努力同所有其他框架 - 或者你可以通过手,如果你正在做MVVM自己做这件事):

http://drc.ideablade.com/devforce-2012/bin/view/Documentation/cocktail-tutorial-talk-to-view

实施例:

1)定义接口IView其中ViewModel(​​)将从你的IView交谈View与所需的方法(或多个)

public interface IView 
{ 
    void AddTextBoxToGrid(); 
} 

2)继承代码后面View和实施IView.AddTextboxToGrid()方法

public partial class View : IView 
{ 
    public void AddTextBoxToGrid() 
    { 
     // implement here your custom view logic using standard code behind; 
    } 
} 

3)添加类型的属性210你​​

public class ViewModel 
{ 
    public IView View { get; set; } 
} 

4)设置View财产上​​到View实例作为IView 例如在代码背后DataContext.View =这是IView;或者在Caliburn中,您可以使用IScreen。OnViewAttached覆盖方法)

public partial class View : IView 
{ 
    public View() 
    { 
     // access you VM by strategy of your framework or choice - this example is when you store your VM in View's DataContext 
     (DataContext as ViewModel).View = this as IView; 
    } 

    public void AddTextBoxToGrid() 
    { 
     // implement here your custom view logic using standard code behind; 
    } 
} 

5)在您的​​通话IView.AddTextboxToGrid()

public class ViewModel 
{ 
    public IView View { get; set; } 

    public void AddTextBoxToGrid() 
    { 
     if (View == null) return; 
     View.AddTextBoxToGrid() 
    } 
} 
+2

最好使用构造函数注入来将'IVew'实例发送到'ViewModel'(我的意思是,'ViewModel'类'构造函数应该接受'IView'实例)。 –

+0

优秀的答案...... :)谢谢@nihique – ankurtr

+5

需要强调的是,在视图中从viewmodel创建依赖关系并不是最纯粹的mvvm。当你使用'(DataContext作为SomeViewModel)'时,你的视图变得依赖于'SomeViewModel',这可能是不希望的。你怎么看? – heltonbiker

1

您也可以在视图后面的代码中使用View的DataContext(它是ViewModel),并将文本框添加到网格中。这会更有意义。

如果您在网格中为您的XAML文件命名,您将能够立即访问后面代码中的网格。

3

您应该将您的创建代码移动到View,并且ViewModel应该在应该调用它时通知视图。

-1

要VIEWMODE拿出像

不要你的代码隐藏和捕捉目标控制放弃视图模型之前使用事件处理程序的xaml instade

This为您提供一个新层,你可以建立自己的体系结构是这样 MVVM => MV(C)VM

0

如果使用的是卡利微,执行以下步骤:

  1. 使视图模型从接口IViewAware继承;你将实现这个接口的两个方法AttachView和GetView。

  2. 定义类型视图的变量获得参考查看

  3. 请参见下面的细节:

    private SomeViewClass v; 
    public void AttachView(object view, object context = null) 
    { 
        v = view as BomView; 
        if (ViewAttached != null) 
         ViewAttached(this, 
         new ViewAttachedEventArgs() { Context = context, View = view }); 
    } 
    
    public object GetView(object context = null) 
    { 
        return v; 
    } 
    

以后你可以通过在浏览访问单个元素v例如v.txtName =“John”;等等...

+0

BomView = SomeViewClass。视图类的名称。 –

相关问题