使用Prism提供的类实现WPF MVVM点餐Demo
使用Prism提供的类实现WPF MVVM点餐Demo
由于公司开发的技术需求,近期在学习MVVM模式开发WPF应用程序。进过一段时间的学习,感受到:学习MVVM模式,最好的方法就是用MVVM做几个Demo,因为编程里面的东西还是原来的WPF的相关知识。最近学习的资料来源大多为CodePlex、CodeProject和MSDN,以及博客园MS的MVP刘铁锰的一些资料。
前面几篇博文DebugLZQ写了,如何来写MVVM,以及Prism框架的安装等等。
本篇在前面的基础上,通过一个相对复杂一点的Demo,来学习Prism中的一些类的使用。
首先来介绍下今天这个Demo要实现的功能,今天开启的系统是XP,所以下面各位看到的将是XP风格的界面。:

·界面上方TextBlock显示餐馆的信息(粉红色字),该信息保存在一个ViewModel的一个餐馆的属性中。
·DataGrid显示菜品信息,从一个模拟的Service中读出;并在最后添加一个CheckBox Binding一个命令用来选择菜品
·下面的TextBox显示选中了几个菜,Button则Binding一个Command实现点菜(象征性的存入本地磁盘)
下面来实现它:
//---------------------
最终的项目的文件结构如下:

前面说过,可以直接饮用Prism,只引入相关的程序集也可以(虽然是一回事),这次我们就这么干!
1.新建一个WpfPrism的WPF项目,添加Prism dll引用,(使用NotificationObject、DelegateCommand)如下:

2.在项目中添加一个Data文件夹,放入Data.XML文件,文件如下:
3.在项目中添加Model文件夹。添加两个Model Dish和Restaurant,分别如下:
4.在项目中添加Services文件夹,其中IDataService、XMLDataService用来定义和实现:获取菜品信息功能。IOrderService和MockOrderService用来定义和实现:点菜功能。之所以使用接口,是为了定义和实现相分离!
其代码依次如下:
5.在项目中添加一个ViewModels文件夹,并添加两个Model:DishMenuItemViewModel和MianWindowViewModel。
稍微解释一下:MianWindowViewModel中的一个属性是List<MianWindowViewModel>类型的。两者代码分别如下:

using Microsoft.Practices.Prism.ViewModel;
using WpfPrism.Models; namespace WpfPrism.ViewModels
{
class DishMenuItemViewModel:NotificationObject
{
public Dish Dish { get; set; } private bool isSelected;
public bool IsSelected//这个地方刚开始写错了,废了太大的劲才找出来(注意拼写!)
{
get { return isSelected; }
set
{
isSelected = value;
RaisePropertyChanged("IsSelected");
}
}
}
}


using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Prism.ViewModel;
using WpfPrism.Models;
using WpfPrism.Services;
using Microsoft.Practices.Prism.Commands;
using System.Windows; namespace WpfPrism.ViewModels
{
class MianWindowViewModel:NotificationObject
{
private Restaurant restaurant;
public Restaurant Restaurant
{
get { return restaurant; }
set
{
restaurant = value;
RaisePropertyChanged("Restaurant");
}
} //外加的一个属性,点菜的数量
private int count;
public int Count
{
get { return count; }
set
{
count = value;
RaisePropertyChanged("Count");
}
} private List<DishMenuItemViewModel> dishMenu;
public List<DishMenuItemViewModel> DishMenu
{
get { return dishMenu; }
set
{
dishMenu = value;
RaisePropertyChanged("DishMenu");
}
} public MianWindowViewModel()
{
LoadRestuarant();//赋值Restaurant属性
LoadDishMenu();//赋值DishMenu属性 //初始化两个命令属性
PlaceOrderCommand = new DelegateCommand(new Action(PlaceOrderCommandExecute));
SelectMenuItemCommand = new DelegateCommand(new Action(SelectMenuItemCommandExecute));
} private void LoadRestuarant()
{
Restaurant = new Restaurant() {Name="百年苏韵", Address="江苏大学", PhoneNumber="0511-12345678"};
} private void LoadDishMenu()
{
DishMenu = new List<DishMenuItemViewModel>(); IDataService ds = new XMLDataService();
var dishes = ds.GetAllDishes();
foreach (var d in dishes)
{
DishMenuItemViewModel item = new DishMenuItemViewModel() { Dish=d};
DishMenu.Add(item);
}
} //两个命令属性
public DelegateCommand PlaceOrderCommand { get; set; }
public DelegateCommand SelectMenuItemCommand { get; set; } private void PlaceOrderCommandExecute()
{
//获取点菜单
var selectedDishes = dishMenu.Where(d => d.IsSelected == true).Select(d => d.Dish.Name).ToList(); //仅保存到本地磁盘--可以写一些有意义的代码
IOrderService orderService = new MockOrderService();
orderService.PlaceOrder(selectedDishes ); MessageBox.Show("订餐成功!");
} private void SelectMenuItemCommandExecute()
{
Count = DishMenu.Count(n=>n.IsSelected==true);
} }
}

注意NotificationObject是ViewModel的基类。
最后,为View添加Binding:

<Window x:Class="WpfPrism.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="590">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 餐馆信息-->
<StackPanel Grid.Row="0">
<StackPanel Orientation="Horizontal" >
<TextBlock Text="欢迎光临-" FontSize="40"/>
<TextBlock Text="{Binding Restaurant.Name}" FontSize="40" Foreground="HotPink" />
</StackPanel>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="地址:" FontSize="40"/>
<TextBlock Text="{Binding Restaurant.Address}" FontSize="40" Foreground="HotPink" />
</StackPanel>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="电话:" FontSize="40"/>
<TextBlock Text="{Binding Restaurant.PhoneNumber}" FontSize="40" Foreground="HotPink" />
</StackPanel>
</StackPanel>
<!--菜品信息,选菜-->
<DataGrid Grid.Row="1" ItemsSource="{Binding DishMenu}" AutoGenerateColumns="False" GridLinesVisibility="All" CanUserDeleteRows="False" CanUserAddRows="False" >
<DataGrid.Columns>
<!-- 这4个来自(ViewModel )Dish属性,UI上一次读出,不会变-->
<DataGridTextColumn Header="菜名" Binding="{Binding Dish.Name}" Width="120"/>
<DataGridTextColumn Header="种类" Binding="{Binding Dish.Category}" Width="120"/>
<DataGridTextColumn Header="点评" Binding="{Binding Dish.Comment}" Width="120"/>
<DataGridTextColumn Header="推荐指数" Binding="{Binding Dish.Score}" Width="120"/>
<!--注意这个属性-->
<DataGridTemplateColumn Header="选中" SortMemberPath="IsSelected" Width="120">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<CheckBox IsChecked="{Binding Path=IsSelected,UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center" HorizontalAlignment="Center"
Command="{Binding Path=DataContext.SelectMenuItemCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<!--所点菜品个数,点菜-->
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" >
<TextBlock Text="点了几个菜?" TextAlignment="Center" />
<TextBox IsReadOnly="True" Text="{Binding Count}" Width="120" TextAlignment="Center" />
<Button Content="点菜" Command="{Binding PlaceOrderCommand}"/>
</StackPanel>
</Grid>
</Window>


using System.Windows;
using WpfPrism.ViewModels; namespace WpfPrism
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent(); this.DataContext = new MianWindowViewModel();
}
}
}

程序运行如下:

可以在D盘找到如下的txt文件:

也请参考CodeProject:WPF Master Details MVVM Application
说明:本文使用Prism框架中的几个类,来简化MVVM的编写。并未所见标准Prism的Bootstrapper、Shell、Region、Module、Unity/MEF...
关于Prism框架的知识,请关注DebugLZQ后续博文:
Prism框架-Hello Prism Using Unity
没什么高端的知识,老鸟绕过轻拍~
希望对你有帮助~
使用Prism提供的类实现WPF MVVM点餐Demo的更多相关文章
- .NET Core 3 WPF MVVM框架 Prism系列之命令
本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的命令的用法 一.创建DelegateCommand命令 我们在上一篇.NET Core 3 WPF MVVM框架 Prism系列之 ...
- .NET Core 3 WPF MVVM框架 Prism系列之导航系统
本文将介绍如何在.NET Core3环境下使用MVVM框架Prism基于区域Region的导航系统 在讲解Prism导航系统之前,我们先来看看一个例子,我在之前的demo项目创建一个登录界面: 我们看 ...
- 1: 介绍Prism5.0 Introduction to the Prism Library 5.0 for WPF(英汉对照版)
Prism provides guidance designed to help you more easily design and build rich, flexible, and easy- ...
- .NET Core 3 WPF MVVM框架 Prism系列之模块化
本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的应用程序的模块化 前言 我们都知道,为了构成一个低耦合,高内聚的应用程序,我们会分层,拿一个WPF程序来说,我们通过MVVM模式 ...
- .NET Core 3 WPF MVVM框架 Prism系列之事件聚合器
本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的使用事件聚合器实现模块间的通信 一.事件聚合器 在上一篇 .NET Core 3 WPF MVVM框架 Prism系列之模块化 ...
- WPF MVVM 从Prism中学习设计模式之Event Aggregator 模式
Prism简介 Prism是由微软Patterns & Practices团队开发的项目,目的在于帮助开发人员构建松散耦合的.更灵活.更易于维护并且更易于测试的WPF应用或是Silverlig ...
- .NET Core 3 WPF MVVM框架 Prism系列之对话框服务
本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的对话框服务,这也是prism系列的最后一篇完结文章,下面是Prism系列文章的索引: .NET Core 3 WPF MVVM框 ...
- .NET Core 3 WPF MVVM框架 Prism系列文章索引
.NET Core 3 WPF MVVM框架 Prism系列之数据绑定 .NET Core 3 WPF MVVM框架 Prism系列之命令 .NET Core 3 WPF MVVM框架 Prism系列 ...
- WPF/MVVM 快速开始指南(译)(转)
WPF/MVVM 快速开始指南(译) 本篇文章是Barry Lapthorn创作的,感觉写得很好,翻译一下,做个纪念.由于英文水平实在太烂,所以翻译有错或者译得不好的地方请多指正.另外由于原文是针对W ...
随机推荐
- CSDN markdown 编辑 第五章 UML
这里大概只能产生两种类型的图: 序列图 框图 序列图 ```sequence A->B: 一句话证明你非常寂寞. Note right of B: thinking B->B: count ...
- hdu 5072 Coprime(同色三角形+容斥)
pid=5072">http://acm.hdu.edu.cn/showproblem.php?pid=5072 单色三角形模型 现场赛和队友想了3个小时,最后发现想跑偏了.感觉好可惜 ...
- Web在线视频方案浅谈
写在前面 最近因为项目预研,花时间和精力了解并总结了现如今web在线视频的一些解决方案,由于资历薄浅,措辞或是表述难免出现遗漏,还望各位海涵,有好的建议或方案还望赐教,定细心学习品位. 如今的web技 ...
- Java内存模型-jsr133规范介绍(转)
最近在看<深入理解Java虚拟机:JVM高级特性与最佳实践>讲到了线程相关的细节知识,里面讲述了关于java内存模型,也就是jsr 133定义的规范. 系统的看了jsr 133规范的前面几 ...
- HTTP Cookie深入理解
HTTP Cookie 概述:Cookie通常也叫做网站cookie,浏览器cookie或者http cookie,是保存在用户浏览器端的,并在发出http请求时会默认携带的一段文本片段.它可以用来做 ...
- Python基本语法[二],python入门到精通[四] (转)
写在前面 python你不去认识它,可能没什么,一旦你认识了它,你就会爱上它 回到顶部 v正文开始:Python基本语法 1.定义常量: 之所以上篇博客介绍了定义变量没有一起介绍定义常量,是因为Pyt ...
- GeeksforGeeks - Adjacency List邻接矩阵C\C++代码
邻接矩阵的图示: 构建一个这种无向邻接矩阵. 參考站点: http://www.geeksforgeeks.org/graph-and-its-representations/ 这里写了个类,添加删除 ...
- JUnit4.8.2来源分析-2 org.junit.runner.Request
JUnit4.8.2源代码,最为yqj2065兴趣是org.junit.runner.Request,现在是几点意味着它? ①封装JUnit的输入 JUnit4作为信息处理单元,它的输入是单元測试类- ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(10)- VSS源代码管理
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(10)- VSS源代码管理 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 ( ...
- ftp设置(2015-04-04)[转]
anonymous_enable=YES /允许匿名访问 12行local_enable=YES /允许本地用户访问(/etc/passwd中的用户) 15行write_enable=YES /允许写 ...