说明:本文出处:http://www.cnblogs.com/DebugLZQ/archive/2012/12/17/2821772.html
·界面上方TextBlock显示餐馆的信息(粉红色字),该信息保存在一个ViewModel的一个餐馆的属性中。
·DataGrid显示菜品信息,从一个模拟的Service中读出;并在最后添加一个CheckBox Binding一个命令用来选择菜品
·下面的TextBox显示选中了几个菜,Button则Binding一个Command实现点菜(象征性的存入本地磁盘)
下面来实现它:
//---------------------
最终的项目的文件结构如下:
前面说过,可以直接饮用Prism,只引入相关的程序集也可以(虽然是一回事),这次我们就这么干!
1.新建一个WpfPrism的WPF项目,添加Prism dll引用,(使用NotificationObject、DelegateCommand)如下:
2.在项目中添加一个Data文件夹,放入Data.XML文件,文件如下:
1 View Code 2 3 <?xml version="1.0" encoding="utf-8"?> 4 <Dishes> 5 <Dish> 6 <Name>土豆泥底披萨</Name> 7 <Category>披萨</Category> 8 <Comment>本店特色</Comment> 9 <Score>4.5</Score> 10 </Dish> 11 <Dish> 12 <Name>烤囊底披萨</Name> 13 <Category>披萨</Category> 14 <Comment>本店特色</Comment> 15 <Score>5</Score> 16 </Dish> 17 <Dish> 18 <Name>水果披萨</Name> 19 <Category>披萨</Category> 20 <Comment></Comment> 21 <Score>4</Score> 22 </Dish> 23 <Dish> 24 <Name>牛肉披萨</Name> 25 <Category>披萨</Category> 26 <Comment></Comment> 27 <Score>5</Score> 28 </Dish> 29 <Dish> 30 <Name>培根披萨</Name> 31 <Category>披萨</Category> 32 <Comment></Comment> 33 <Score>4.5</Score> 34 </Dish> 35 <Dish> 36 <Name>什锦披萨</Name> 37 <Category>披萨</Category> 38 <Comment></Comment> 39 <Score>4.5</Score> 40 </Dish> 41 <Dish> 42 <Name>金枪鱼披萨</Name> 43 <Category>披萨</Category> 44 <Comment></Comment> 45 <Score>5</Score> 46 </Dish> 47 <Dish> 48 <Name>海鲜披萨</Name> 49 <Category>披萨</Category> 50 <Comment></Comment> 51 <Score>5</Score> 52 </Dish> 53 <Dish> 54 <Name>川香披萨</Name> 55 <Category>披萨</Category> 56 <Comment></Comment> 57 <Score>4.5</Score> 58 </Dish> 59 <Dish> 60 <Name>黑椒鸡腿扒</Name> 61 <Category>特色主食</Category> 62 <Comment>本店特色</Comment> 63 <Score>5</Score> 64 </Dish> 65 <Dish> 66 <Name>肉酱意面</Name> 67 <Category>特色主食</Category> 68 <Comment>本店特色</Comment> 69 <Score>5</Score> 70 </Dish> 71 <Dish> 72 <Name>寂寞小章鱼</Name> 73 <Category>风味小吃</Category> 74 <Comment></Comment> 75 <Score>5</Score> 76 </Dish> 77 <Dish> 78 <Name>照烧鸡软骨</Name> 79 <Category>风味小吃</Category> 80 <Comment></Comment> 81 <Score>5</Score> 82 </Dish> 83 <Dish> 84 <Name>芝士青贝</Name> 85 <Category>风味小吃</Category> 86 <Comment></Comment> 87 <Score>4.5</Score> 88 </Dish> 89 <Dish> 90 <Name>奥尔良烤翅</Name> 91 <Category>风味小吃</Category> 92 <Comment>秒杀KFC</Comment> 93 <Score>5</Score> 94 </Dish> 95 <Dish> 96 <Name>双酱煎泥肠</Name> 97 <Category>风味小吃</Category> 98 <Comment></Comment> 99 <Score>4</Score>100 </Dish>101 <Dish>102 <Name>香酥鱿鱼圈</Name>103 <Category>风味小吃</Category>104 <Comment>本店特色</Comment>105 <Score>4.5</Score>106 </Dish>107 <Dish>108 <Name>黄金蝴蝶虾</Name>109 <Category>风味小吃</Category>110 <Comment>本店特色</Comment>111 <Score>5</Score>112 </Dish>113 <Dish>114 <Name>金枪鱼沙拉</Name>115 <Category>沙拉</Category>116 <Comment>本店特色</Comment>117 <Score>5</Score>118 </Dish>119 <Dish>120 <Name>日式素沙拉</Name>121 <Category>沙拉</Category>122 <Comment></Comment>123 <Score>5</Score>124 </Dish>125 <Dish>126 <Name>冰糖洛神</Name>127 <Category>饮料</Category>128 <Comment></Comment>129 <Score>5</Score>130 </Dish>131 <Dish>132 <Name>玫瑰特饮</Name>133 <Category>饮料</Category>134 <Comment></Comment>135 <Score>5</Score>136 </Dish>137 <Dish>138 <Name>清新芦荟</Name>139 <Category>饮料</Category>140 <Comment></Comment>141 <Score>5</Score>142 </Dish>143 <Dish>144 <Name>薄荷汽水</Name>145 <Category>饮料</Category>146 <Comment>本店特色</Comment>147 <Score>5</Score>148 </Dish>149 </Dishes>
3.在项目中添加Model文件夹。添加两个Model Dish和Restaurant,分别如下:
1 View Code 2 3 namespace WpfPrism.Models 4 { 5 class Dish 6 { 7 public string Name { get; set; } 8 9 public string Category { get; set; }10 11 public string Comment { get; set; }12 13 public string Score { get; set; }14 }15 }
1 View Code 2 3 namespace WpfPrism.Models 4 { 5 class Restaurant 6 { 7 public string Name { get; set; } 8 9 public string Address { get; set; }10 11 public string PhoneNumber { get; set; }12 }13 }
1 View Code 2 3 namespace WpfPrism.Models 4 { 5 class Restaurant 6 { 7 public string Name { get; set; } 8 9 public string Address { get; set; }10 11 public string PhoneNumber { get; set; }12 }13 }
4.在项目中添加Services文件夹,其中IDataService、XMLDataService用来定义和实现:获取菜品信息功能。IOrderService和MockOrderService用来定义和实现:点菜功能。之所以使用接口,是为了定义和实现相分离!
其代码依次如下:
1 View Code 2 3 using System.Collections.Generic; 4 using WpfPrism.Models; 5 6 namespace WpfPrism.Services 7 { 8 interface IDataService 9 {10 List<Dish> GetAllDishes();11 }12 }
1 View Code 2 3 using System; 4 using System.Collections.Generic; 5 using WpfPrism.Models; 6 using System.IO; 7 using System.Xml.Linq; 8 9 10 namespace WpfPrism.Services11 {12 class XMLDataService:IDataService//接口:定义和实现相分离13 {14 #region IDataService 成员15 16 public List<Models.Dish> GetAllDishes()17 {18 List<Dish> dishList = new List<Dish>();19 20 string xmlFile = Path.Combine(Environment.CurrentDirectory, @"Data/Data.xml");21 22 XDocument xDoc = XDocument.Load(xmlFile);23 var dishes = xDoc.Descendants("Dish");24 foreach (var d in dishes)25 {26 Dish dish = new Dish();27 dish.Name = d.Element("Name").Value;28 dish.Category = d.Element("Category").Value;29 dish.Comment = d.Element("Comment").Value;30 dish.Score = d.Element("Score").Value;31 dishList.Add(dish);32 }33 34 return dishList;35 }36 37 #endregion38 }39 }
1 View Code 2 3 using System.Collections.Generic; 4 5 namespace WpfPrism.Services 6 { 7 interface IOrderService 8 { 9 void PlaceOrder(List<string> dishes);10 }11 }
1 View Code 2 3 using System.Collections.Generic; 4 using System.IO; 5 6 namespace WpfPrism.Services 7 { 8 class MockOrderService:IOrderService//接口:实现定义和实现相分离 9 {10 #region IOrderService 成员11 12 public void PlaceOrder(List<string> dishes)13 {14 File.WriteAllLines(@"D:/order.txt", dishes.ToArray());15 }16 17 #endregion18 }19 }
5.在项目中添加一个ViewModels文件夹,并添加两个Model:DishMenuItemViewModel和MianWindowViewModel。
稍微解释一下:MianWindowViewModel中的一个属性是List<MianWindowViewModel>类型的。两者代码分别如下:
1 using Microsoft.Practices.Prism.ViewModel; 2 using WpfPrism.Models; 3 4 namespace WpfPrism.ViewModels 5 { 6 class DishMenuItemViewModel:NotificationObject 7 { 8 public Dish Dish { get; set; } 9 10 private bool isSelected;11 public bool IsSelected//这个地方刚开始写错了,废了太大的劲才找出来(注意拼写!)12 {13 get { return isSelected; }14 set 15 {16 isSelected = value;17 RaisePropertyChanged("IsSelected");18 }19 }20 }21 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using Microsoft.Practices.Prism.ViewModel; 5 using WpfPrism.Models; 6 using WpfPrism.Services; 7 using Microsoft.Practices.Prism.Commands; 8 using System.Windows; 9 10 namespace WpfPrism.ViewModels11 {12 class MianWindowViewModel:NotificationObject13 {14 private Restaurant restaurant;15 public Restaurant Restaurant16 {17 get { return restaurant; }18 set19 {20 restaurant = value;21 RaisePropertyChanged("Restaurant");22 }23 }24 25 //外加的一个属性,点菜的数量26 private int count;27 public int Count28 {29 get { return count; }30 set31 {32 count = value;33 RaisePropertyChanged("Count");34 }35 }36 37 private List<DishMenuItemViewModel> dishMenu;38 public List<DishMenuItemViewModel> DishMenu39 {40 get { return dishMenu; }41 set42 {43 dishMenu = value;44 RaisePropertyChanged("DishMenu");45 }46 }47 48 public MianWindowViewModel()49 {50 LoadRestuarant();//赋值Restaurant属性51 LoadDishMenu();//赋值DishMenu属性52 53 //初始化两个命令属性54 PlaceOrderCommand = new DelegateCommand(new Action(PlaceOrderCommandExecute));55 SelectMenuItemCommand = new DelegateCommand(new Action(SelectMenuItemCommandExecute));56 }57 58 private void LoadRestuarant()59 {60 Restaurant = new Restaurant() {Name="百年苏韵", Address="江苏大学", PhoneNumber="0511-12345678"}; 61 }62 63 private void LoadDishMenu()64 {65 DishMenu = new List<DishMenuItemViewModel>();66 67 IDataService ds = new XMLDataService();68 var dishes = ds.GetAllDishes();69 foreach (var d in dishes)70 {71 DishMenuItemViewModel item = new DishMenuItemViewModel() { Dish=d};72 DishMenu.Add(item);73 }74 }75 76 //两个命令属性77 public DelegateCommand PlaceOrderCommand { get; set; }78 public DelegateCommand SelectMenuItemCommand { get; set; }79 80 private void PlaceOrderCommandExecute()81 {82 //获取点菜单83 var selectedDishes = dishMenu.Where(d => d.IsSelected == true).Select(d => d.Dish.Name).ToList();84 85 //仅保存到本地磁盘--可以写一些有意义的代码86 IOrderService orderService = new MockOrderService();87 orderService.PlaceOrder(selectedDishes );88 89 MessageBox.Show("订餐成功!");90 }91 92 private void SelectMenuItemCommandExecute()93 {94 Count = DishMenu.Count(n=>n.IsSelected==true);95 }96 97 }98 }
注意NotificationObject是ViewModel的基类。
最后,为View添加Binding:
1 <Window x:Class="WpfPrism.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="590"> 5 <Grid> 6 <Grid.RowDefinitions> 7 <RowDefinition Height="Auto"/> 8 <RowDefinition Height="*"/> 9 <RowDefinition Height="Auto"/>10 </Grid.RowDefinitions>11 <!-- 餐馆信息-->12 <StackPanel Grid.Row="0">13 <StackPanel Orientation="Horizontal" >14 <TextBlock Text="欢迎光临-" FontSize="40"/>15 <TextBlock Text="{Binding Restaurant.Name}" FontSize="40" Foreground="HotPink" />16 </StackPanel>17 <StackPanel Orientation="Horizontal" >18 <TextBlock Text="地址:" FontSize="40"/>19 <TextBlock Text="{Binding Restaurant.Address}" FontSize="40" Foreground="HotPink" />20 </StackPanel>21 <StackPanel Orientation="Horizontal" >22 <TextBlock Text="电话:" FontSize="40"/>23 <TextBlock Text="{Binding Restaurant.PhoneNumber}" FontSize="40" Foreground="HotPink" />24 </StackPanel>25 </StackPanel>26 <!--菜品信息,选菜-->27 <DataGrid Grid.Row="1" ItemsSource="{Binding DishMenu}" AutoGenerateColumns="False" GridLinesVisibility="All" CanUserDeleteRows="False" CanUserAddRows="False" >28 <DataGrid.Columns>29 <!-- 这4个来自(ViewModel )Dish属性,UI上一次读出,不会变-->30 <DataGridTextColumn Header="菜名" Binding="{Binding Dish.Name}" Width="120"/>31 <DataGridTextColumn Header="种类" Binding="{Binding Dish.Category}" Width="120"/>32 <DataGridTextColumn Header="点评" Binding="{Binding Dish.Comment}" Width="120"/>33 <DataGridTextColumn Header="推荐指数" Binding="{Binding Dish.Score}" Width="120"/>34 <!--注意这个属性-->35 <DataGridTemplateColumn Header="选中" SortMemberPath="IsSelected" Width="120">36 <DataGridTemplateColumn.CellTemplate>37 <DataTemplate >38 <CheckBox IsChecked="{Binding Path=IsSelected,UpdateSourceTrigger=PropertyChanged}"39 VerticalAlignment="Center" HorizontalAlignment="Center" 40 Command="{Binding Path=DataContext.SelectMenuItemCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}}"/>41 </DataTemplate>42 </DataGridTemplateColumn.CellTemplate>43 </DataGridTemplateColumn>44 </DataGrid.Columns>45 </DataGrid>46 <!--所点菜品个数,点菜-->47 <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" >48 <TextBlock Text="点了几个菜?" TextAlignment="Center" />49 <TextBox IsReadOnly="True" Text="{Binding Count}" Width="120" TextAlignment="Center" />50 <Button Content="点菜" Command="{Binding PlaceOrderCommand}"/>51 </StackPanel>52 </Grid>53 </Window>
1 using System.Windows; 2 using WpfPrism.ViewModels; 3 4 namespace WpfPrism 5 { 6 /// <summary> 7 /// MainWindow.xaml 的交互逻辑 8 /// </summary> 9 public partial class MainWindow : Window10 {11 public MainWindow()12 {13 InitializeComponent();14 15 this.DataContext = new MianWindowViewModel();16 }17 }18 }
可以在D盘找到如下的txt文件:
心得:学习Prism MVVM唯一的方法就是多看优秀的代码、多写代码、多多思考,才能理解其模式原理!
联系客服