首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WPF MVVM设计问题

WPF MVVM设计问题
EN

Stack Overflow用户
提问于 2013-05-10 08:26:27
回答 2查看 1.7K关注 0票数 2

我正在构建一个基于WPF的销售点系统来练习使用MVVM.我没有使用任何MVVM框架,而是在Josh Smith http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030的文章中使用了http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030类。

我以前写过一个,没有应用MVVM模式(仍然使用WPF)。

对于数据库访问,我使用了实体框架。看起来是这样的:

我的问题是,如何使用MVVM实现这一点?首先,我已经使用MVVM编写了Login窗口,我的直接问题是,

  1. 如何关闭Login窗口(释放它)并打开MainWindow
  2. 在非MVVM版本中,MainWindow只包含屏幕截图的顶部部分,即按钮行。
  3. 我是否应该将“按钮条”进一步拆分为自己的ViewViewModel,只将MainWindow用作将所有东西组合在一起的地方?
  4. 如果是这样的话,我如何编码:当单击按钮时,“按钮条”的ViewModel将告诉MainWindowViewModel将各自的Views (在非MVVM版本中使用System.Windows.Controls.Page )加载到Frame中?在非MVVM版本中,我使用的代码相当简单: 私有空btnCheckout_Click(对象发送方,RoutedEventArgs e) { mainFrame.Navigated += frame_Navigated;var pgCheckout =新pgCheckout();mainFrame.Navigate(pgCheckout);//框架}
  5. 如果不是,如何将另一个Page加载到Frame中?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-10 09:30:41

如果您不使用任何现有的框架,您将不得不自己创建一个框架。海事组织,你可以从中受益,因为你控制了一切,但你也必须重新发明很多东西。我可以描述我们是如何做到的,无论它是对是错,让这里的投票决定:)

首先,您不想用任何与UI相关的对象来污染ViewModel代码。但是,ViewModel是关于视图逻辑的,您需要以某种方式控制表示(导航、用户消息.)。因此,您可以在视图模型中引入某种视图服务,它控制与视图相关的逻辑,但不依赖UI框架中的任何内容。我们可以这样说:

代码语言:javascript
运行
复制
public interface IViewService
{
   //show message dialog with message text
   void ShowMessageDialog(string message);
   //show Yes/No message dialog with message text. Retrun true if answer is Yes 
   bool AskQuestion(string message);
   //Navigate to some other viewmodel
   void NavigateTo(ViewModel someOtherViewModel);      
}

您必须使用WPF相关逻辑创建这种服务的具体实现。如何实现该方法取决于您和您正在使用的UI框架(在本例中是WPF)。

在视图模型中,您需要以某种方式获得实现IViewService的对象。您可以通过使用依赖项注入来注入它,使用服务定位器获取实例,甚至有一些硬编码的静态单例实例。(IMO依赖项注入是一种方法,但也使事情更加复杂,您需要引入DI容器并使用DI容器创建所有视图模型实例)。

在命令中,您可以调用服务的方法。

假设您的LoginCommand of your LoginViewModel (登录按钮绑定到的RelayCommand)

代码语言:javascript
运行
复制
private void ExecuteLoginCommand(object parameter)
{
      bool loginOk = Login(.....);
      if(loginOk)
         viewService.NavigateTo(new MainWindowViewModel);
      else
         viewService.ShowMessage("Login failed");
}

最重要的是,ViewModel控制着与表示相关的逻辑,但对UI框架却一无所知。所有的"WPF“代码都在实现IViewService的类中。在您的视图模型中,您的“程序到接口”(),因此您没有与WPF逻辑紧密耦合,您的viewmodels是“可测试的”,您甚至可以在其他UI平台上重用相同的视图模型代码。

票数 1
EN

Stack Overflow用户

发布于 2013-05-10 08:52:51

解决这些问题的一种方法是创建一个负责加载和卸载视图的对象。

在应用程序开始时,将创建该对象的一个实例,该对象将显示一个窗口(该窗口将显示所有视图),创建一个ViewModel和一个视图的实例,将视图的DataContext设置为ViewModel,并将视图传递到窗口以便显示(例如,将其设置为网格的子实例)

若要关闭视图和/或打开另一个视图:当执行当前ViewModel的命令时,可以向同一个对象发送消息。对象可以向窗口发出关闭当前视图的信号,并可以以打开第一个视图的方式打开一个新视图。该命令甚至可以传递一个指示必须加载的ViewModel的参数。

要发送消息,我建议使用使用弱事件的MessageBroker来传递消息。如果不使用弱事件,则应用程序面临占用内存的风险,因为事件处理程序阻止垃圾收集清理。请参阅MVVM灯用于这样一个信使

关于你的问题:

  1. 按照上面的步骤。
  2. 与任何其他应用程序一样,是否拆分ViewModels和视图是一个重用和分解的问题。
  3. 不要对点击事件进行编码。执行传递所需的视图、ViewModel和容器(ContentControl?)的命令。它将承载视图。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16477994

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档