2013-01-09 39 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。視圖類的名稱。 –

相關問題