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
How can i access a control in mvvm model in viewmodel?
提问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 IView
in which ViewModel
(VM
) will talk to View
with the required method(s)
1)定义接口IView
,其中ViewModel
( VM
) 将View
与所需的方法对话
public interface IView
{
void AddTextBoxToGrid();
}
2) Inherit code behind View
from your IView
and implement IView.AddTextboxToGrid()
method
2)从你的和实现方法后面继承代码View
IView
IView.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 IView
to your VM
3)将 type 属性添加IView
到您的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:
4)将View
属性设置VM
View
为IView
例如在后面的代码中的实例:
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 VM
call 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,请执行以下步骤:
Make the ViewModel inherited from interface
IViewAware
; you are going to implement two methods AttachView and GetView of this interface.Define a variable with type of View to get the reference to the View
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; }
使 ViewModel 继承自 interface
IViewAware
;您将要实现此接口的两个方法 AttachView 和 GetView。定义一个 View 类型的变量来获取对 View 的引用
请参阅下面的详细信息:
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"; 等等...