使用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

Hello Prism Using MEF

没什么高端的知识,老鸟绕过轻拍~

希望对你有帮助~

 

使用Prism提供的类实现WPF MVVM点餐Demo的更多相关文章

  1. .NET Core 3 WPF MVVM框架 Prism系列之命令

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的命令的用法 一.创建DelegateCommand命令 我们在上一篇.NET Core 3 WPF MVVM框架 Prism系列之 ...

  2. .NET Core 3 WPF MVVM框架 Prism系列之导航系统

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism基于区域Region的导航系统 在讲解Prism导航系统之前,我们先来看看一个例子,我在之前的demo项目创建一个登录界面: 我们看 ...

  3. 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- ...

  4. .NET Core 3 WPF MVVM框架 Prism系列之模块化

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的应用程序的模块化 前言  我们都知道,为了构成一个低耦合,高内聚的应用程序,我们会分层,拿一个WPF程序来说,我们通过MVVM模式 ...

  5. .NET Core 3 WPF MVVM框架 Prism系列之事件聚合器

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的使用事件聚合器实现模块间的通信 一.事件聚合器  在上一篇 .NET Core 3 WPF MVVM框架 Prism系列之模块化 ...

  6. WPF MVVM 从Prism中学习设计模式之Event Aggregator 模式

    Prism简介 Prism是由微软Patterns & Practices团队开发的项目,目的在于帮助开发人员构建松散耦合的.更灵活.更易于维护并且更易于测试的WPF应用或是Silverlig ...

  7. .NET Core 3 WPF MVVM框架 Prism系列之对话框服务

     本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的对话框服务,这也是prism系列的最后一篇完结文章,下面是Prism系列文章的索引: .NET Core 3 WPF MVVM框 ...

  8. .NET Core 3 WPF MVVM框架 Prism系列文章索引

    .NET Core 3 WPF MVVM框架 Prism系列之数据绑定 .NET Core 3 WPF MVVM框架 Prism系列之命令 .NET Core 3 WPF MVVM框架 Prism系列 ...

  9. WPF/MVVM 快速开始指南(译)(转)

    WPF/MVVM 快速开始指南(译) 本篇文章是Barry Lapthorn创作的,感觉写得很好,翻译一下,做个纪念.由于英文水平实在太烂,所以翻译有错或者译得不好的地方请多指正.另外由于原文是针对W ...

随机推荐

  1. myeclipse egit 安装失败 org.eclipse.e4.ui.css.swt.theme 0.0.0

    [前言] 首先确保您可能会被安装在阅读本文之前,myeclipse egit, 见文章:http://blog.csdn.net/uikoo9/article/details/17247405 事实上 ...

  2. Docker container communication with ovs

    2台宿主机,192.168.11153,192.168.1.154 安装OVS rpm -ivh openvswitch-2.4.0-1.x86_64.rpm #预先下载的 配置OVS 1. 按照上一 ...

  3. 一个Bug的反思

    对输入数据判重,使用Map,将对象作为Key,使用map的containsKey方法来着重是否是重复记录.正常的处理流程:(1)将输入的数据封装成对象(2)判重,将没有重复的数据存储到map(3)对没 ...

  4. hdu4419 Colourful Rectangle 12年杭州网络赛 扫描线+线段树

    题意:给定n个矩形,每个矩形有一种颜色,RGB中的一种.相交的部分可能为RG,RB,GB,RGB,问这n个矩形覆盖的面积中,7种颜色的面积分别为多少 思路:把x轴离散化做扫描线,线段树维护一个扫描区间 ...

  5. hdu 3695 Computer Virus on Planet Pandora(AC自己主动机)

    题目连接:hdu 3695 Computer Virus on Planet Pandora 题目大意:给定一些病毒串,要求推断说给定串中包括几个病毒串,包括反转. 解题思路:将给定的字符串展开,然后 ...

  6. 从源码看Android中sqlite是怎么读DB的(转)

    执行query 执行SQLiteDatabase类中query系列函数时,只会构造查询信息,不会执行查询. (query的源码追踪路径) 执行move(里面的fillwindow是真正打开文件句柄并分 ...

  7. react.js 从零开始(五)React 中事件的用法

    事件系统   虚拟事件对象 事件处理器将会传入虚拟事件对象的实例,一个对浏览器本地事件的跨浏览器封装.它有和浏览器本地事件相同的属性和方法,包括 stopPropagation() 和 prevent ...

  8. C++ Web Programming

    一般的网关接口或者CGI,就是一个标准的集合.它定义信息怎样再问吧server和一般脚本间的交换. CGI的说明书是由NCSA维护,NCSA定义CGI的范畴:一般的网关接口或者CGI是外部网关程序的一 ...

  9. 十天学Linux内核之第七天---电源开和关时都发生了什么

    原文:十天学Linux内核之第七天---电源开和关时都发生了什么 说实话感觉自己快写不下去了,其一是有些勉强跟不上来,其二是感觉自己越写越差,刚开始可能是新鲜感以及很多读者的鼓励,现在就是想快点完成自 ...

  10. 网络资源(7) - JAX-WS视频

    2014_08_25 http://v.youku.com/v_show/id_XNjMzNDcyMTk2.html 基于JAX-WS编程模型的WebService 1. @WebService注释类 ...