WPF 小项目实例—点餐系统
这是我学习WPF的时候按照WPF深入浅出视频教学中的项目敲的代码,使用了MVVM Light框架;
效果图:
项目文件框架:
然后按照上面文件来介绍项目结构:
首先需要添加管理NuGet程序包:MVVM Light
一、Data文件夹下的Data.xml文件
这是一个模仿数据库的文件,存放菜单信息:
<?xml version="1.0" encoding="utf-8" ?>
<Diahes>
<Dish>
<Name>水煮肉片</Name>
<Category>徽菜</Category>
<Comment>招牌菜</Comment>
<Score>9.7</Score>
<Price>45元</Price>
</Dish>
<Dish>
<Name>椒盐龙虾</Name>
<Category>川菜</Category>
<Comment>招牌菜</Comment>
<Score>9.2</Score>
<Price>43元</Price>
</Dish>
<Dish>
<Name>京酱猪蹄</Name>
<Category>湘菜</Category>
<Comment>招牌菜</Comment>
<Score>9.8</Score>
<Price>51元</Price>
</Dish>
<Dish>
<Name>爆炒鱿鱼</Name>
<Category>徽菜</Category>
<Comment>招牌菜</Comment>
<Score>9.3</Score>
<Price>54元</Price>
</Dish>
<Dish>
<Name>可乐鸡翅</Name>
<Category>湘菜</Category>
<Comment>招牌菜</Comment>
<Score>9.4</Score>
<Price>44元</Price>
</Dish>
<Dish>
<Name>凉拌龙须</Name>
<Category>湘菜</Category>
<Comment>凉拌</Comment>
<Score>8.6</Score>
<Price>18元</Price>
</Dish>
<Dish>
<Name>麻辣花生</Name>
<Category>湘菜</Category>
<Comment>凉拌</Comment>
<Score>8.7</Score>
<Price>19元</Price>
</Dish>
<Dish>
<Name>韭菜炒肉</Name>
<Category>湘菜</Category>
<Comment>炒菜</Comment>
<Score>9.4</Score>
<Price>25元</Price>
</Dish>
<Dish>
<Name>青椒肉丝</Name>
<Category>湘菜</Category>
<Comment>炒菜</Comment>
<Score>9.1</Score>
<Price>26元</Price>
</Dish>
<Dish>
<Name>红烧茄子</Name>
<Category>湘菜</Category>
<Comment>招牌菜</Comment>
<Score>9.4</Score>
<Price>24元</Price>
</Dish>
<Dish>
<Name>红烧排骨</Name>
<Category>湘菜</Category>
<Comment>招牌菜</Comment>
<Score>9.4</Score>
<Price>42元</Price>
</Dish>
<Dish>
<Name>番茄蛋汤</Name>
<Category>湘菜</Category>
<Comment>招牌菜</Comment>
<Score>9.4</Score>
<Price>21元</Price>
</Dish>
<Dish>
<Name>山药炒肉</Name>
<Category>湘菜</Category>
<Comment>招牌菜</Comment>
<Score>9.4</Score>
<Price>27元</Price>
</Dish>
<Dish>
<Name>极品肥牛</Name>
<Category>湘菜</Category>
<Comment>招牌菜</Comment>
<Score>9.4</Score>
<Price>58元</Price>
</Dish>
<Dish>
<Name>香拌牛肉</Name>
<Category>湘菜</Category>
<Comment>招牌菜</Comment>
<Score>9.4</Score>
<Price>48元</Price>
</Dish>
<Dish>
<Name>手撕包菜</Name>
<Category>湘菜</Category>
<Comment>招牌菜</Comment>
<Score>9.4</Score>
<Price>16元</Price>
</Dish>
<Dish>
<Name>香辣花甲</Name>
<Category>湘菜</Category>
<Comment>招牌菜</Comment>
<Score>9.4</Score>
<Price>36元</Price>
</Dish>
<Dish>
<Name>酸菜鱼</Name>
<Category>湘菜</Category>
<Comment>招牌菜</Comment>
<Score>9.4</Score>
<Price>56元</Price>
</Dish>
</Diahes>
并设置文件属性:
二、Models文件夹下的两个类
1.Dish类:每一道菜的几个属性,和上面xml文件数据对应
public class Dish
{
public string Name { get; set; }
public string Category { get; set; }
public string Comment { get; set; }
public double Score { get; set; }
public string Price { get; set; }
}
2.Restaurant类:用于显示餐馆信息的类
public class Restaurant
{
public string Name { get; set; }
public string Address{ get; set; }
public string PhoneNumber { get; set; }
}
三、Services文件夹下的服务类
1.IDataService接口:
public interface IDataService
{
List<Dish> GetDishes();
}
2.IOrderService接口:
interface IOrderService
{
void PlaceOrder(List<string> dishes);
}
3.MockOrderService类:记录点餐内容
class MockOrderService : IOrderService
{
public void PlaceOrder(List<string> dishes)
{
System.IO.File.WriteAllLines(@"D:\order.txt",dishes.ToArray());
}
}
4.XmlDataService类:获取Data.xml所有菜品的信息用于后续展示在界面上:
class XmlDataService : IDataService
{
public List<Dish> GetDishes()
{
List<Dish> dishList = new List<Dish>();
string xmlFileName = System.IO.Path.Combine(Environment.CurrentDirectory,@"Data\Data.xml");
XDocument xDoc = XDocument.Load(xmlFileName);
var dishes = xDoc.Descendants("Dish");
foreach (var d in dishes)
{
Dish dish = new Dish();
dish.Name = d.Element("Name").Value;
dish.Category = d.Element("Category").Value;
dish.Comment = d.Element("Comment").Value;
dish.Score = double.Parse(d.Element("Score").Value);
dish.Price = d.Element("Price").Value;
dishList.Add(dish);
}
return dishList;
}
}
四、ViewModel层:
1.DishMenuItemViewModel:菜品是否被选中
public class DishMenuItemViewModel : ViewModelBase
{
public Dish Dish { get; set; }
private bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set { isSelected = value; RaisePropertyChanged(); }
}
}
2.MainViewModel,最主要的后台类,界面绑定的属性和命令都在这里
public class MainViewModel : ViewModelBase
{
public RelayCommand PlaceOrderCommand { get; set; }
public RelayCommand SelectMenuItemCommand { get; set; }
private int count;
public int Count
{
get { return count; }
set { count = value; RaisePropertyChanged(); }
}
private Restaurant restaurant;
public Restaurant Restaurant
{
get { return restaurant; }
set { restaurant = value; RaisePropertyChanged(); }
}
private List<DishMenuItemViewModel> dishMenu;
public List<DishMenuItemViewModel> DishMenu
{
get { return dishMenu; }
set { dishMenu = value; RaisePropertyChanged(); }
}
public MainViewModel()
{
this.LoadRestaurant();
this.LoadDishMenu();
//PlaceOrderCommand = new RelayCommand(PlaceOrderCommandExecute);
//SelectMenuItemCommand = new RelayCommand(SelectMenuItemExecute);
PlaceOrderCommand = new RelayCommand(new Action(PlaceOrderCommandExecute));
SelectMenuItemCommand = new RelayCommand(new Action(SelectMenuItemExecute));
}
private void LoadRestaurant()
{
this.Restaurant = new Restaurant();
this.Restaurant.Name = "聚贤庄";
this.Restaurant.Address = "xx省xx市xx区xx街道xx楼xx层xx号(很难找!)";
this.Restaurant.PhoneNumber = "188888888888 or 6666-6666666";
}
private void LoadDishMenu()
{
XmlDataService ds = new XmlDataService();
var dishes = ds.GetDishes();
this.DishMenu = new List<DishMenuItemViewModel>();
foreach (var dish in dishes)
{
DishMenuItemViewModel item = new DishMenuItemViewModel();
item.Dish = dish;
this.DishMenu.Add(item);
}
}
private void PlaceOrderCommandExecute()
{
var selectedDishes = this.DishMenu.Where(i => i.IsSelected == true).Select(i => i.Dish.Name).ToList();
IOrderService orderService = new MockOrderService();
orderService.PlaceOrder(selectedDishes);
MessageBox.Show("订餐成功!");
}
private void SelectMenuItemExecute()
{
this.Count = this.DishMenu.Count(i => i.IsSelected == true);
}
}
五、界面部分:
MainWindow.xaml代码
<Window x:Class="WPFDish0701.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFDish0701"
mc:Ignorable="d"
Title="{Binding Restaurant.Name,StringFormat=\{0\}-在线订餐}" Height="600" Width="1000" WindowStartupLocation="CenterScreen">
<Border BorderBrush="Orange" BorderThickness="3" CornerRadius="6" Background="AliceBlue">
<Grid x:Name="Root" Margin="4">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Border BorderBrush="Orange" BorderThickness="1" CornerRadius="6" Padding="4">
<StackPanel>
<StackPanel Orientation="Horizontal">
<StackPanel.Effect>
<DropShadowEffect Color="LightGray"/>
</StackPanel.Effect>
<TextBlock Text="欢迎光临-" FontSize="60" FontFamily="LiShu"/>
<TextBlock Text="{Binding Restaurant.Name}" FontSize="60" FontFamily="LiShu"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="小店地址:" FontSize="24" FontFamily="LiShu"/>
<TextBlock Text="{Binding Restaurant.Address}" FontSize="24" FontFamily="LiShu"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="订餐电话:" FontSize="24" FontFamily="LiShu"/>
<TextBlock Text="{Binding Restaurant.PhoneNumber}" FontSize="24" FontFamily="LiShu"/>
</StackPanel>
</StackPanel>
</Border>
<DataGrid AutoGenerateColumns="False" GridLinesVisibility="None" CanUserDeleteRows="False" CanUserAddRows="False" Margin="0,4" Grid.Row="1" FontSize="16" ItemsSource="{Binding DishMenu}">
<DataGrid.Columns>
<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"/>
<DataGridTextColumn Header="价格" Binding="{Binding Dish.Price}" 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=DataGrid}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="2">
<TextBlock Text="共计" VerticalAlignment="Center"/>
<TextBox IsReadOnly="True" TextAlignment="Center" Width="120" Text="{Binding Count}" Margin="4,0"/>
<Button Content="Order" Height="24" Width="120" Command="{Binding PlaceOrderCommand}"/>
</StackPanel>
</Grid>
</Border>
</Window>
MainWindow.xaml.cs代码
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}