我是C 开发人员,是WPF和MVVM的新开发人员。如果我选择任何错误的单词来问我的问题
,请忍受我我在 mfc/c 中有我的主要应用程序,该应用程序将一些数据传递到C#库( cli 用作中间层(。在 c#library 中,有一个代码部分打开对话框,填充数据,并以下面的方式通知了调用对象 -
public classA()
{
MyDialog dlg = new MyDialog(param1, param2, param3)
if(dlg.ShowDialog().GetValueOrDefault())
{
var name = dlg.name;
var roll = dlg.roll;
}
else
{
var name = string.Empty;
var roll = string.Empty;
}
}
现在使用 MVVM 模式进行了修改和实现对话框。
我已经创建了以下文件作为实现的一部分 - 1
- mydialogview.xaml
- mydialogview.xaml.cs
- myDialogViewModel.cs
- myDialogModel.cs
我的问题是,如何从我的 classa 中实例化新对话框,以便使用以前使用的对话框传递给对话框并记录用户选择而不会丢失任何内容的参数填充数据数据并安全地关闭视图。
标准MVVM方法是这样的(至少在使用MVVM Light时(:
- 您有一个VM层,一个类库。
- 您有一个视图层,WPF控制库或WPF应用程序。
- 视图层将引用引用到VM层。VM层对视图一无所知。
-
您为对话框的VM创建一个普通的公共类。称其为
DialogVM
或其他。确保此类从MVVM Light的内置ViewModelBase
继承。这将使您访问MVVM Light提供的更改通知方法。在您的情况下可能看起来像这样:public partial class DialogVM : ViewModelBase { private string _Name; public string Name { get { return _Name; } set { Set(ref _Name, value); } } private string _Roll; public string Roll { get { return _Roll; } set { Set(ref _Roll, value); } } }
-
vm层具有称为
ViewModelLocator
的全局静态类。该课程执行IOC/DI,并提供公共静态属性以揭示不同的VM。(在您的情况下,对话框的VM转到VM项目,ViewModelLocator
看起来像这样:using System; namespace VMLayer { public class ViewModelLocator { static ViewModelLocator() { SimpleIoc.Default.Register<DialogVM>(true); } public static DialogVM MyDialog => SimpleIoc.Default.GetInstance<DialogVM>(); } }
-
您的对话框(A
Window
(转到视图层,并使用此裸露属性MyDialog
为对话框提供DataContext
:<Window x:Class="GlasshouseTestingShell.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:vm="clr-namespace:VMLayer;assembly=VMLayer" DataContext="{x:Static vm:ViewModelLocator.MyDialog}" d:DataContext="{d:DesignInstance Type=vm:DialogVM}"> </Window>
- 看我们如何干净地创建了视图层的
DataContext
,而无需在视图层中编写C#代码的一行。这也很优雅,因为您在Binding
表达式和其他地方获得了所有设计时间Intellisense。 -
现在,您将所有UI东西(文本框,按钮等(绑定到对话框VM公开的公共属性和命令。在代码方面仍然没有行。在您的情况下可能看起来像这样:
<TextBox Text="{Binding Name}" />
其余的东西在C 中:
- 您在C 项目中添加对视图和VM DLL的引用。
- 创建对话框的对象。它将自动实例化其VM并执行绑定。您致电
ShowDialog()
将其带到屏幕。 - 使用在对话框中采取操作,最后按确定或取消。
- 您捕获对话框结果,然后访问对话框对象的
DataContext
属性,该属性是DialogVM
类的对象。您可以从其中访问其中的用户提供的值,因为绑定已在VM中为您更新了这些属性。
我不确定我遵循您的所有要求,但这大致是我如何处理这样的任务的方式:
在A类中实例化视图和ViewModel
在ViewModel上设置您想要的任何参数。作为属性或通过构造函数注入。
将视图的数据台面设置为ViewModel。
您需要绑定的一切都应该在它们之间绑定。
showdialog视图。
用户在视图中编辑并更改持续到ViewModel属性。
他们完成了编辑,然后您将使用ViewModel属性。也许其中之一就是您提到的模型。也许该模型是由ViewModel实例化的,以获取数据或Clasta,如果这更方便。在后一种情况下,您可能必须将该模型传递给ViewModel。
牢记上述。
一些粗糙的代码:
public class ClassA
{
MyDialogViewModel vm = new MyDialogViewModel { Name = "X", Roll = "Y" };
MyDialog dlg = new MyDialog();
dlg.ShowDialog();
var name = vm.Name;
var roll = vm.roll;
// Do something to persist your data as necessary. Either here or in a model within the viewmodel
}
名称和滚动大概可以绑定到视图中的某些文本框文本属性。
如果它像获得两个字符串值一样简单,那么我认为实际上拥有一个模型没有任何优势。另一方面,如果处理的涉及更多,那么当然,ViewModel可能会实例化模型。
myDialogViewModel应该实现InotifyPropertyChanged,并且您需要绑定的任何东西都应该是公共财产。不确定您是否需要属性汇总通知,但请始终实施。可选地筹集从物业设定器换的属性。