关于弹出搜索的WPF MVVM建议

时间:2012-07-09 09:24:35

标签: c# wpf mvvm

我是WPF MVVM模型的新手,所以请耐心等待。我正在努力编写一个库存管理系统。我有一个维护页面,我成功链接到我的viewmodels。但是,我想启用一个搜索控件,我可以从维护页面触发,弹出一个网格,用户可以在其中搜索某个项目,选择它并返回维护屏幕,所选项目为showm。

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

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

4 个答案:

答案 0 :(得分:2)

解决问题的好方法是使用User Interaction Patterns

  

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

     

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

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

答案 1 :(得分:1)

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

控件可以像这样使用:

<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,您的搜索网格将显示在维护屏幕的前面。

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

如果您在编写弹出窗口时表示Dialog,那么我将使用像this一样的对话服务。

在维护viewmodel opencommand中:

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;