1) 新建Silverlight Application,然后再.Web项目中添加相应数据库的Entity Data Model 数据模型。
2) 在.Web项目中添加中间层DomainService,来用于在Silverlight Application中访问Entity Data Model数据库。
3) 设计UI界面MainPage.xaml:
<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SLCrazyElephant.Client.MainPage"
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:viewModel="clr-namespace:SLCrazyElephant.Client.ViewModels"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<viewModel:MainWindowViewModel x:Key="viewModel"/>
</UserControl.Resources>
<StackPanel x:Name="stackPanel">
<TextBlock Text="{Binding Restaurant.Name}" Margin="5"/>
<TextBlock Text="{Binding Restaurant.Address}" Margin="5"/>
<TextBlock Text="{Binding Restaurant.Phone}" Margin="5"/>
<sdk:DataGrid AutoGenerateColumns="False" IsReadOnly="True" ItemsSource="{Binding DishItem,Mode=TwoWay}" x:Name="dataGrid">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="菜品" Binding="{Binding Dish.Name}"/>
<sdk:DataGridTextColumn Header="种类" Binding="{Binding Dish.Category}"/>
<sdk:DataGridTextColumn Header="点评" Binding="{Binding Dish.Comment}"/>
<sdk:DataGridTextColumn Header="推荐分数" Binding="{Binding Dish.Score}"/>
<sdk:DataGridTemplateColumn Header="选中" Width="120">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected,Mode=TwoWay}" VerticalAlignment="Center" HorizontalAlignment="Center" Command="{Binding SelectMenuItemCommand,Source={StaticResource viewModel}}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<!--<sdk:DataGridTemplateColumn Header="功能" Width="Auto">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="删除" Margin="10" Command="{Binding DeleteCommand,Source={StaticResource viewModel}}" Height="24"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>-->
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock Text="合计" VerticalAlignment="Center"/>
<TextBox IsReadOnly="True" TextAlignment="Center" Width="120" Text="{Binding Count,Mode=TwoWay}" Margin="5"/>
<Button Content="Order" Height="24" Width="120" Command="{Binding OrderCommand}"/>
<Button Content="Delete" Height="24" Width="120" Command="{Binding DeleteCommand}"/>
</StackPanel>
</StackPanel>
</UserControl>
注意 这里的 CheckBox的Command使用了Source={StaticResource viewModel} 是因为在DataGrid里的CheckBox无法触发该Command命令,需要在xaml里实例化一个。ViewModel后,在触发该ViewModel里的Comand方法,这也导致了合计Count不好使(暂时还不知道如何解决)。
4) 该View对应的ViewModel:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Practices.Prism.ViewModel;
using SLCrazyElephant.Web;
using System.Collections.Generic;
using Microsoft.Practices.Prism.Commands;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Collections.ObjectModel;
namespace SLCrazyElephant.Client.ViewModels
{
public class MainWindowViewModel:NotificationObject
{
//DomainService客户端代理类
private RestaurantDomainContext _RestaurantDomainContext = new RestaurantDomainContext();
//数据属性
private Restaurant restaurant;
public Restaurant Restaurant
{
get { return restaurant; }
set
{
this.restaurant = value;
this.RaisePropertyChanged("Restaurant");
}
}
//一定要用ObservableCollection泛型类型的 否则无法在删除完DishItem后直接在UI上刷新最新的DishItem
private ObservableCollection<DishMenuItemViewModel> dishItem;
public ObservableCollection<DishMenuItemViewModel> DishItem
{
get { return dishItem; }
set
{
this.dishItem = value;
this.RaisePropertyChanged("DishItem");
}
}
private int count;
public int Count
{
get { return count; }
set
{
this.count = value;
this.RaisePropertyChanged("Count");
}
}
//命令属性
public DelegateCommand OrderCommand { get; set; }
public DelegateCommand SelectMenuItemCommand { get; set; }
public DelegateCommand DeleteCommand { get; set; }
public void DeleteCommandExecute()
{
//删除选中的数据 这里删不掉 因为删除的对象必须是原声的Dish对象,新建的对象是无法删除的。
//Two objects of same type and attributes do not necessarily mean they are same, by same they should be on the same memory location.
//You need to find the item that matches the same attributes in your datasoure and then delete that.
var selectedDishes = this.DishItem.Where(i => i.IsSelected == true);
foreach (var s in selectedDishes)
{
//先把选择的Dish菜名的Name传入到方法里,查询出对应数据库中的Dish对象
var query = this._RestaurantDomainContext.GetSelectedDishQuery(s.Dish.Name);
this._RestaurantDomainContext.Load(query, (lo) =>
{
//然后再删除
this._RestaurantDomainContext.Dishes.Remove(lo.Entities.First());
//由于Load方法是延时处理方法,所以SubmitChange要放到这里来处理,不能放在外面
this._RestaurantDomainContext.SubmitChanges();
MessageBox.Show(string.Format("{0}删除成功",lo.Entities.First().Name));
//为了删除后直接在DataGrid上刷新出最新删除后的状态
this.DishItem.Remove(s);
}, null
);
}
}
public void OrderCommandExecute()
{
//存储到数据库里操作
List<OrderedDish> odList = new List<OrderedDish>();
try
{
var orderedDishes = this.DishItem.Where(i => i.IsSelected == true);
foreach (var dish in orderedDishes)
{
OrderedDish od = new OrderedDish();
od.Score = dish.Dish.Score;
od.Category = dish.Dish.Category;
od.Comment = dish.Dish.Comment;
od.Name = dish.Dish.Name;
//od.Score = 87;
//od.Name = "Name1";
//od.Category = "C1";
//od.Comment = "Comment1";
this._RestaurantDomainContext.OrderedDishes.Add(od);
}
//var s = this._RestaurantDomainContext.OrderedDishes;
this._RestaurantDomainContext.SubmitChanges();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public void SelectMenuItemCommandExecute()
{
//算出Count的值
this.Count = this.DishItem.Where(i => i.IsSelected == true).Count();
}
public MainWindowViewModel()
{
this.LoadRestaurant();
this.LoadDishMenu();
this.OrderCommand = new DelegateCommand(new Action(this.OrderCommandExecute));
this.SelectMenuItemCommand = new DelegateCommand(new Action(this.SelectMenuItemCommandExecute));
this.DeleteCommand = new DelegateCommand(new Action(this.DeleteCommandExecute));
}
private void LoadDishMenu()
{
//加载菜品列表
var query = _RestaurantDomainContext.GetDishQuery();
_RestaurantDomainContext.Load(query, (lo) =>
{
//先从DomainService里取出Dish的所有对象
var dishList = lo.Entities.ToList();
//创建一个新的List<DishMenuItemViewModel>对象组
this.DishItem = new ObservableCollection<DishMenuItemViewModel>();
DishItem.Clear();
//foreach循环把从数据库取出的Dish赋给Item的Dish属性,这样就可以保证有Dish和IsSelected两个属性
foreach (var dish in dishList)
{
DishMenuItemViewModel item = new DishMenuItemViewModel();
item.Dish = dish;
this.DishItem.Add(item);
}
}, null
);
}
private void LoadRestaurant()
{
//指定query为GetRestaurantQuery()的引用
var query = _RestaurantDomainContext.GetRestaurantQuery();
//然后Load该query,并且把Query出来的对象赋给Restaurant属性,这里一定要保证using System.Linq;要不没法直接使用.First()方法
_RestaurantDomainContext.Load(query, (lo) =>
{
this.Restaurant = lo.Entities.First();
}, null
);
}
}
}
这里需要注意:
dishItem必须要定义为ObservableCollection类型的属性,否则(例如改为List类型的)无法在删除数据的时候马上刷新DataGrid。
删除数据的时候需要把源edmx里的数据先查询出来后在删除,不要考虑使用new一个新对象的方法来删除,这样是无法找到要删除的对象的,这是由于new出来的对象并不是真正在内存里的原对象,而且要记得在删除成功后使用DishItem.Remove()方法来改变DishItem属性,从而使得UI上的DataGrid也产生刷新操作。
5) 采用了在ViewModel中有一个的方法,新建了一个DishMenu的ViewModel:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SLCrazyElephant.Web;
using Microsoft.Practices.Prism.ViewModel;
using Microsoft.Practices.Prism.Commands;
namespace SLCrazyElephant.Client.ViewModels
{
public class DishMenuItemViewModel:NotificationObject
{
private Dish dish;
public Dish Dish
{
get { return this.dish; }
set
{
this.dish = value;
this.RaisePropertyChanged("Dish");
}
}
private bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set
{
this.isSelected = value;
this.RaisePropertyChanged("IsSelected");
//MessageBox.Show("IsSelected");
}
}
}
}
数据库可使用在项目中的DB.sql脚本生成。
源代码: http://download.youkuaiyun.com/detail/eric_k1m/6746223