2

我对 WPF MVVM 模型很陌生,所以请多多包涵。我正在尝试编写一个库存管理系统。我有一个维护页面,我成功链接到我的视图模型。但是,我想启用一个可以从维护页面触发的搜索控件,以弹出一个网格,用户可以在其中搜索一个项目,选择它并返回到维护屏幕,并显示所选项目。

如何在 MVVM 中实现这种类型的功能最好?维护屏幕上的搜索按钮可以链接到搜索 ICommand,但 Viewmodel 不了解 UI,因此它不知道显示搜索控件的名称或如何显示它。我能想到的唯一想法是在 UI 后面的代码中编写搜索按钮事件,但这不会破坏 MVVM 模式吗?

如果这是一个愚蠢的问题,请提前致谢并道歉。

4

4 回答 4

2

解决问题的一个好方法是使用用户交互模式

就 MVVM 模式而言,视图模型负责启动与用户的交互以及消费和处理任何响应,而视图负责使用任何适当的用户体验实际管理与用户的交互。保持视图模型中实现的表示逻辑与视图实现的用户体验之间的关注点分离,有助于提高可测试性和灵活性。

在 MVVM 模式中实现这些类型的用户交互有两种常见的方法。一种方法是实现一个服务,视图模型可以使用该服务来启动与用户的交互,从而保持其对视图实现的独立性。另一种方法使用视图模型引发的事件来表达与用户交互的意图,以及绑定到这些事件并管理交互的视觉方面的视图中的组件。

这是用于执行 DialogServices 等的 MVVM 模式,因此它也符合您的要求。

于 2012-07-09T10:19:02.903 回答
1

这里的主要问题是如何以 MVVM 友好的方式显示搜索弹出窗口。我的github 帐户上有一个为此目的而设计的自定义控件的示例(完整的源代码可供下载)。

该控件可以这样使用:

<c:ModalContentPresenter IsModal="{Binding DialogIsVisible}">

    <!-- This is the main content e.g. your maintenance screen -->
    <TabControl Margin="5">
            <Button Margin="55"
                    Padding="10"
                    Command="{Binding ShowModalContentCommand}">
                This is the primary Content
            </Button>
        </TabItem>
    </TabControl>

    <c:ModalContentPresenter.ModalContent>
        <!-- This is the modal content e.g. your search popup -->
        <Button Margin="75"
                Padding="50"
                Command="{Binding HideModalContentCommand}">
            This is the modal content
        </Button>
    </c:ModalContentPresenter.ModalContent>

</c:ModalContentPresenter>

模态内容直接显示在主要内容上(在您的情况下为维护屏幕),其可见性由IsModal可以绑定到 viewModel 中的属性的属性控制。该属性将由搜索命令设置为 true,并且您的搜索网格将显示在维护屏幕的前面。

您的搜索屏幕“视图”将有一个关闭按钮,该按钮绑定到另一个 ICommand 对象,该对象只是将属性设置为 false 并隐藏弹出内容。

请注意,无需“传递”任何信息,因为主要内容和模态内容都由同一控件管理,因此它们共享相同的DataContext内容,在您的情况下,这将是对您的 viewModel 的引用。

于 2012-07-09T10:37:33.663 回答
0

为了避免 UI 和视图模型之间的直接耦合,我之前使用了一个调解器将新 UI 元素的创建转发回 UI 类。但是,我从来没有完全相信这种方法,所以有兴趣看看是否有人有更好的解决方案。

于 2012-07-09T09:44:51.577 回答
0

如果您在编写弹出窗口时指的是对话框,那么我会使用像这样的对话框服务。

在您的维护视图模型中打开命令:

var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);//in your case the viewmodel for your search

//check the result and just take the SelectedItem from your dialogwindowVM
if(result)
  this._selected = dialogwindowVM.MySelectedItem;
于 2012-07-09T11:17:53.383 回答