使用MVVM显示新窗口,并获得更新数据(Using MVVM show new window and

2019-08-16 22:18发布

我工作的一个WPF MVVM应用。 我显示在DataGrid中的一些数据。 我有两个按钮来添加和编辑所选择的记录。 我在视图模型数据,我已经表现出另一个窗口(View),并确保的ViewModels应该没有关于视图的信息。 我应该在哪里创建视图和视图模型? 如何取回数据并更新数据网格? 我怎样才能在MVVM实现这一目标? 我们还没有决定使用任何框架,所以我创造我自己的界面。

Answer 1:

注:该结束了相当长的答案-请问我,如果有不清楚的地方

对话窗口的实现是在MVVM设计一个有争议的问题,不同的人用不同的方法。

和你一样,我已经决定不使用任何框架,并用手实现最多的事。 当涉及到对话窗口,我选择以务实约我实现MVVM的,从我的ViewModel内启动对话窗口。 另外,我允许每个对话视图模型具有它被显示在窗口的引用,因此它可以关闭它在适当的时候(下面详细说明)。 这打破了一些严格的MVVM“规则”,但它能够完成任务。

这样做的主要缺点是,它可能会破坏单元测试,如果你正在测试的东西,通过一个对话框去。 但是,你可以走很长的路,而不会在这个问题到现在也没有打扰我呢。

我已经建立了一下对话框的ViewModels,我可以轻松地扩展库的。 这是太多的代码张贴在这里,但我会告诉你的亮点。

基本视图模型的对话框

我的每个对话窗口具有从继承的视图模型DialogViewModelBase ,这是类同我经常ViewModelBase ,它提供了支持INotifyPropertyChanged等有趣的是这种公开的方法,这是我从哪里启动对话框拨打:

/// <summary>
/// Creates window instance for this dialog viewmodel and displays it, getting the dialog result.
/// </summary>
public void ShowDialogWindow()
{
    // This is a property of the DialogViewModelBase class - thus, each DialogViewModel holds a reference to its own DialogWindow:
    this.DialogWindow = new Dialogs.Views.DialogWindow();
    // Tell the DialogWindow to display this ViewModel:
    this.DialogWindow.DataContext = this;
    // Launch the Window, using a method of the Window baseclass, that only returns when the window is closed:
    this.DialogWindow.ShowDialog();
}

当它的窗口在上面的方法启动将关闭Window.DialogResult属性设置。 这就是为什么DialogWindow是的属性DialogViewModelBase类-当子类对话ViewModel要关闭对话窗口,它只是设置的结果:

protected void CloseDialogWithResult(bool dialogWindowResult)
{
    // Setting this property automatically closes the dialog window:
    this.DialogWindow.DialogResult = dialogWindowResult;
}

宿主窗口的对话框查看

所述Dialogs.Views.DialogWindow该类ShowDialogWindow方法实例在XAML定义,并且是一个子类Window 。 它有两个重要特征。 第一个是它的主要内容元素是一个简单的ContentControl结合所述当前上下文。 这让我定义不同的Views对于不同的子类DialogViewModelBaseDialogWindow将举办相应的View基于上下文的类型:

<ContentControl Content="{Binding}" /> <!-- In reality this is inside a border etc but its simplified here for demonstration -->

在的第二个重要特征DialogWindow XAML是,它定义了对话Views与对话去ViewModels 。 下面是一个例子:

<Window.Resources>
    <!-- DEFAULT ViewModel-View TEMPLATES -->

    <DataTemplate DataType="{x:Type dialogs:YesNoMessageBoxDialogViewModel}">
        <views:MessageBoxView />
    </DataTemplate>

    <DataTemplate DataType="{x:Type dialogs:ErrorDialogViewModel}">
        <views:ErrorDialogView/>            
    </DataTemplate>

</Window.Resources>

所有这一切呢,是我可以定义对话框作为子类DialogViewModelBase并实施了View每一个,然后告诉DialogWindow其中ViewContentControl必须显示其对话ViewModel

启动一个对话框,并取得成果

下面是从我的应用程序的一个样本ViewModels ,在我启动一个对话窗口,允许用户选择创造一个资产类型:

public void CreateNewAsset()
{
    // Instantiate desired Dialog ViewModel:
    Dialogs.NewAssetTypeSelectionDialogViewModel dialog = new Dialogs.NewAssetTypeSelectionDialogViewModel();

    // Launch Dialog by calling method on Dialog base class:
    dialog.ShowDialogWindow();

    // Execution will halt here until the Dialog window closes...

    // The user's selection is stored in a property on the dialog ViewModel, and can now be retrieved:
    CalculatorBase.AssetTypeEnum newAssetType = dialog.AssetType;

    switch (newAssetType)
    {
        // Do stuff based on user's selection...
    }
}

PS:我真的应该写这个博客条目-当我这样做,我会在这里发布的链接,博客条目将可能有更完整的代码示例。



Answer 2:

这取决于你是如何处理的数据。 我会认为,在弹出的窗口中所做的更改只有当用户点击像保存在其他情况下,他们应该被丢弃被接受。 所以,首先,我会建议使用MVC方法,因为控制器非常适合此类任务。 你建立它的ViewModels,为它们分配Ø视图,示意见。 虚拟机的只是保存数据和命令,命令执行方法保存在控制器中。 换句话说,你必须负责管理你的虚拟机,并享有单独的类。 你应该看看棱镜框架。 它提供了类似观点regios在那里你可以在运行时注入不同的用户控制,指挥和MVC分层了一起IOC和DI模式框的伟大的事情。



文章来源: Using MVVM show new window and get updates data