我是C ++开发人员,是WPF和MVVM的新手。如果我选择了错误的单词来问我的问题,请忍受我
我在 MFC / C ++ 中有我的Main应用程序,该应用程序将一些数据传递到C#库中( CLI 被用作中间层)。 在 C#库中,有一段代码打开了一个对话框,填充了数据,并通过以下方式将用户选择通知给调用对象-
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
我的问题是,如何现在从我的 classA 实例化新对话框,以便使用传递给对话框的参数以与以前相同的方式填充数据,并记录用户选择而不会丢失任何内容数据并安全地关闭视图。
答案 0 :(得分:2)
标准MVVM方法的工作方式如下(至少在使用MVVM Light时):
您为对话框的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>();
}
}
您的对话框(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
的程度如何。从Binding
表达式和其他地方获得所有设计时Intellisense的角度来看,这也很优雅。您现在将所有UI内容(文本框,按钮等)绑定到对话框VM公开的公共属性和命令。后面的代码中仍然没有一行。在您的情况下,可能看起来像这样:
<TextBox Text="{Binding Name}" />
其余的都是C ++:
ShowDialog()
将其显示在屏幕上。DataContext
属性,该属性是DialogVM
类的对象。绑定已在VM中为您更新了这些属性,因此您可以从中访问用户提供的值。答案 1 :(得分:1)
我不确定我是否会遵循您的所有要求,但这大致就是我将要完成的任务的方式:
实例化类A中的视图和视图模型。
设置所需的视图模型参数。作为属性或通过构造函数注入。
将视图的数据上下文设置为视图模型。
所有需要绑定的东西都应该在它们之间绑定。
显示视图视图。
用户在视图中进行编辑,更改仍保留在视图模型属性中。
它们完成编辑,然后您可以使用viewmodel属性。也许其中之一就是您提到的模型。也许是由视图模型实例化模型以获取数据,或者如果更方便,则由classA实例化。在后一种情况下,您可能必须将该模型传递给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
}
名称和滚动可能绑定到视图中的某些文本框或某些文本属性。
如果只是获取两个字符串值那么简单,那么实际上拥有一个模型就没有任何好处。另一方面,如果更多地涉及处理,那么视图模型当然可以实例化模型。
MyDialogViewModel应该实现inotifypropertychanged,并且您需要绑定的任何东西都应该是一个公共属性。不知道您是否需要属性更改通知,但始终执行它。可以选择从属性设置者处更改属性。