Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在viewmodel中访问mvvm模型中的控件?_C#_Wpf_Silverlight_Mvvm_Devforce - Fatal编程技术网

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

C# 如何在viewmodel中访问mvvm模型中的控件?,c#,wpf,silverlight,mvvm,devforce,C#,Wpf,Silverlight,Mvvm,Devforce,我有一个WPF窗口,在该窗口中我有一个网格 我使用M-V-VM模型,我想在代码中(在viewmodel中)向网格动态添加一个文本框 如何访问网格?您还可以在视图的代码隐藏中使用视图的DataContext(即ViewModel),并将文本框添加到网格中。这会更有意义 如果在XAML文件中为网格命名,您将能够立即在代码中访问网格。您应该将创建代码移动到视图,并且ViewModel应该在调用它时通知View 使用监控控制器模式。 阅读: CaliburnMicro MVVM框架的示例实现如下所示(对

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

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


如何访问网格?

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


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

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

使用监控控制器模式。

阅读:

CaliburnMicro MVVM框架的示例实现如下所示(对所有其他框架都适用-或者,如果您自己在做MVVM,您可以手动完成):

示例:

1) 定义界面
IView
,其中
ViewModel
VM
)将使用所需方法与
View
对话

2) 从您的
IView
继承
查看
后的代码,并实现
IView.AddTextboxToGrid()
方法

public partial class View: IView 
{
    public void AddTextBoxToGrid() 
    {  
        // implement here your custom view logic using standard code behind; 
    }
}
3)
IView
类型的属性添加到
VM

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

    public void AddTextBoxToGrid() 
    {
        if (View == null) return;
        View.AddTextBoxToGrid()
    }
}
4)
VM上的
View
属性设置为
View
的一个实例,作为
IView
e、 g.在代码隐藏中:

 DataContext.View = this as IView; 
或者在Caliburn中,您可以使用IScreen.OnViewAttached覆盖方法)

5) 在
VM
中调用
IView.AddTextboxToGrid()

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

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

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

  • 使ViewModel从界面继承
    IViewAware
    ;您将实现此接口的两个方法AttachView和GetView

  • 定义一个视图类型的变量以获取对视图的引用

  • 详情见下文:

    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”;等等。

    在走这条路之前,我会确保绝对必要,通常从视图模型访问视图是不好的做法,除非绝对没有其他选择。@BenjaminPaul说了什么。使用MVVM时,不从ViewModel添加控件。是的,我知道,这正是我的意思。但是,我有时需要获得视图模型中控件的引用,以满足不支持常规绑定的控件的需要。这也是我所指的场景。最好使用构造函数注入将
    IVew
    实例发送到
    ViewModel
    (我的意思是,
    ViewModel
    class'构造函数应该接受
    IView
    实例)。需要强调的是,从视图中的viewmodel创建依赖项也不是最纯粹的mvvm。使用
    (DataContext作为SomeViewModel)
    时,视图将依赖于
    SomeViewModel
    ,这可能是不需要的。你怎么看?@Mohammaddehan:你将如何使用Caliburn实现这个功能?答案非常清楚。在保持MVVM模式的同时,还有其他选择吗?@heltonbiker为什么这是不可取的?视图总是知道viewmodel(请记住,所有绑定都引用viewmodel的属性),再添加一个直接依赖项不会有任何其他伤害。“禁止”的是viewmodel直接了解视图。BomView=SomeViewClass。视图类的名称。