How can i access a control in mvvm model in viewmodel?

匆匆过客 提交于 2019-11-29 18:57:36
nihique

Use Supervising Controller pattern.

Reading:

Example implementation for CaliburnMicro MVVM framework is shown here (will work same for all other frameworks - or you can do it by hand if you are doing MVVM by yourself):

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

Example:

1) Define interface IView in which ViewModel (VM) will talk to View with the required method(s)

public interface IView 
{
    void AddTextBoxToGrid();
}

2) Inherit code behind View from your IView and implement IView.AddTextboxToGrid() method

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

3) Add a property of type IView to your VM

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

4) Set View property on VM to an instance of View as IView e.g. in code behind:

 DataContext.View = this as IView; 

or in Caliburn you can use IScreen.OnViewAttached override method)

public partial class View: IView 
{
    public View()
    {
        // access you VM by the 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) In your VM call IView.AddTextboxToGrid()

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

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

You should move your creation code to View, and ViewModel should just notify view when it should be called.

You can also use the DataContext (which is the ViewModel) of the View in the code behind of the view, and add the textbox to the grid there. That would make more sense.

If you give the grid a name in your XAML file, you will be able to access the grid in the code behind immediately.

Trong Nguyen

If you are using Caliburn Micro, implement following step:

  1. Make the ViewModel inherited from interface IViewAware; you are going to implement two methods AttachView and GetView of this interface.

  2. Define a variable with type of View to get the reference to the View

  3. See detail below:

    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;
    }
    

Later on you can access a single element on the View through v such as v.txtName="John"; etc...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!