C# 如何在 viewmodel 中访问 mvvm 模型中的控件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14236222/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:07:41  来源:igfitidea点击:

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

c#wpfsilverlightmvvmdevforce

提问by Sanjay Patel

I have a WPF Window, and in that window I have a grid.

我有一个 WPF 窗口,在那个窗口中我有一个网格。

I use M-V-VM model and I want to add a TextBox to the grid dynamically in code(in viewmodel)

我使用 MV-VM 模型,我想在代码中动态地向网格添加一个 TextBox(在视图模型中)

How can I get access to the grid?

我怎样才能访问网格?

采纳答案by nihique

Use Supervising Controllerpattern.

使用监督控制器模式。

Reading:

读:

Example implementation for CaliburnMicroMVVM 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):

此处显示了CaliburnMicroMVVM 框架的示例实现(适用于所有其他框架 - 或者如果您自己执行 MVVM,则可以手动执行):

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

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

Example:

例子:

1) Define interface IViewin which ViewModel(VM) will talk to Viewwith the required method(s)

1)定义接口IView,其中ViewModel( VM) 将View与所需的方法对话

public interface IView 
{
    void AddTextBoxToGrid();
}

2) Inherit code behind Viewfrom your IViewand implement IView.AddTextboxToGrid()method

2)从你的和实现方法后面继承代码ViewIViewIView.AddTextboxToGrid()

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

3) Add a property of type IViewto your VM

3)将 type 属性添加IView到您的VM

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

4) Set Viewproperty on VMto an instance of Viewas IViewe.g. in code behind:

4)View属性设置VMViewIView例如在后面的代码中的实例

 DataContext.View = this as IView; 

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

或在 Caliburn 中,您可以使用 IScreen.OnViewAttached 覆盖方法)

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 VMcall IView.AddTextboxToGrid()

5) 在您的VM来电中IView.AddTextboxToGrid()

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

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

回答by Geerten

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.

您还可以在视图背后的代码中使用视图的 DataContext(即 ViewModel),并将文本框添加到那里的网格中。那会更有意义。

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

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

回答by Lonli-Lokli

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

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

回答by Trong Nguyen

If you are using Caliburn Micro, implement following step:

如果您使用的是 Caliburn Micro,请执行以下步骤:

  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;
    }
    
  1. 使 ViewModel 继承自 interface IViewAware;您将要实现此接口的两个方法 AttachView 和 GetView。

  2. 定义一个 View 类型的变量来获取对 View 的引用

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

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

稍后您可以通过 v 访问 View 上的单个元素,例如 v.txtName="John"; 等等...