MVVM模式學習
以前winform 入門的時候 做了個非常簡單的 生肖查詢器。效果如下:
最近看了些不少資料,發現MVVM 模式挺好用的。
M----model V-----view VM-----viewmodel
具體的不說了,博客園,銀光中國,很多地方都有介紹。 我個人覺得最主要用到的就是 silverlight 的綁定機制。
於是乎就想自己做個簡單的MVVM 例子,想了想就把生肖查詢器給轉換過來了
整個解決方案 的樹形結構如下:
具體代碼示例如下:
AnimalModel
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 System.ComponentModel;
namespace SearchAnimals.Model
{
public class AnimalModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
#region Animal 私?有瓺 屬?性?
private String _Year;
private String _Name;
private String _Image;
#endregion
#region Animal 共2有瓺 屬?性?
public String Year {
get {
return _Year;
}
set {
_Year = value ;
updata( "Year" );
}
}
public String Name {
get {
return _Name;
}
set {
_Name = value ;
updata( "Name" );
}
}
public String Image {
get {
return _Image;
}
set {
_Image = value ;
updata( "Image" );
}
}
#endregion
private void updata( String name) {
if (PropertyChanged != null ) {
PropertyChanged( this , new PropertyChangedEventArgs (name));
}
}
}
}
AnimalView.xaml
< UserControl
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 : SearchAnimals_ViewModel ="clr-namespace:SearchAnimals.ViewModel" xmlns : sdk ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x : Class ="SearchAnimals.View.AnimalView"
mc : Ignorable ="d"
d : DesignHeight ="300" d : DesignWidth ="400">
< UserControl.Resources >
< SearchAnimals_ViewModel : AnimalViewModel x : Key ="AnimalViewModelDataSource" d : IsDataSource ="True"/>
</ UserControl.Resources >
< Grid x : Name ="LayoutRoot" Background ="White" DataContext ="{ Binding Source ={ StaticResource AnimalViewModelDataSource }}">
< Grid.RowDefinitions >
< RowDefinition Height ="1*"/>
< RowDefinition Height ="2*"/>
</ Grid.RowDefinitions >
< Grid Grid.Row ="0">
< Grid.RowDefinitions >
< RowDefinition Height ="1*"/>
< RowDefinition Height ="1*"/>
</ Grid.RowDefinitions >
< Grid.ColumnDefinitions >
< ColumnDefinition Width ="1*"/>
< ColumnDefinition Width ="1*"/>
</ Grid.ColumnDefinitions >
< ComboBox x : Name ="comboBox" Grid.Row ="0" Grid.Column ="0" ItemsSource ="{ Binding ListYear }" FontFamily ="SketchFlow Print" FontSize ="24" HorizontalAlignment ="Center" VerticalAlignment ="Center"/>
< Button Content ="LookUp" Grid.Row ="0" Grid.Column ="1" FontSize ="32" FontFamily ="SketchFlow Print" CommandParameter ="{ Binding SelectedItem , ElementName =comboBox}" Command ="{ Binding SearchCommand , Mode =OneWay}" HorizontalAlignment ="Center" VerticalAlignment ="Center" />
< Button Content ="CopyResult" Grid.Row ="1" Grid.Column ="1" FontSize ="32" FontFamily ="Comic Sans MS" HorizontalAlignment ="Center" VerticalAlignment ="Center" Command ="{ Binding CopyCommand , Mode =OneWay}" />
< sdk : Label Grid.Row ="1" Grid.Column ="0" FontSize ="20" Content ="{ Binding Animal .Name}" HorizontalAlignment ="Center" VerticalAlignment ="Center"/>
</ Grid >
< Grid Grid.Row ="1">
< Grid.Background >
< ImageBrush Stretch ="Fill" ImageSource ="{ Binding Animal .Image}"/>
</ Grid.Background >
< Border BorderBrush ="LightBlue" BorderThickness ="3"/>
</ Grid >
</ Grid >
</ UserControl >
AnimalView.xaml .Cs 無特別內容
AnimalViewModel.cs
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 System.ComponentModel;
using SearchAnimals.Model;
using Microsoft.Expression.Interactivity.Core;
using System.Collections.Generic;
namespace SearchAnimals.ViewModel
{
public class AnimalViewModel:INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region AnimalViewModel 私有屬性
/// <summary>
/// 定義一個 AnimalModel 對象
/// </summary>
private AnimalModel _Animal;
private ICommand _SearchCommand;
private ICommand _CopyCommand;
private List<String> _ListYear;
private String _SelectYear;
#endregion
#region AnimalViewModel 共有屬性
public AnimalModel Animal {
get {
return _Animal;
}
set {
_Animal = value;
updata("Animal");
}
}
public String SelectYear {
get {
return _SelectYear;
}
set {
_SelectYear = value;
updata("SelectYear");
}
}
public ICommand SearchCommand {
get {
if (_SearchCommand == null) _SearchCommand = new ActionCommand(search);
return _SearchCommand;
}
}
public ICommand CopyCommand {
get {
if (_CopyCommand == null) _CopyCommand = new ActionCommand(copy);
return _CopyCommand;
}
}
public List<String> ListYear {
get {
return _ListYear;
}
set {
_ListYear = value;
}
}
#endregion
#region 私有方法
private void updata(String name) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
/// <summary>
/// 更新 選擇生肖
/// </summary>
/// <param name="obj"></param>
private void search(Object obj) {
String year = obj.ToString();
String strName = getAnimalNameByYear(int.Parse(year));
String strImage = "";
switch (strName) {
case "鼠 ":
strImage = "/SearchAnimals;component/Images/animal_shu.jpg";
break;
case "牛 ":
strImage = "/SearchAnimals;component/Images/animal_niu.jpg";
break;
case "虎 ":
strImage = "/SearchAnimals;component/Images/animal_hu.jpg";
break;
case "兔 ":
strImage = "/SearchAnimals;component/Images/animal_tu.jpg";
break;
case "龍 ":
strImage = "/SearchAnimals;component/Images/animal_long.jpg";
break;
case "蛇 ":
strImage = "/SearchAnimals;component/Images/animal_shejpg";
break;
case "馬 ":
strImage = "/SearchAnimals;component/Images/animal_ma.jpg";
break;
case "羊 ":
strImage = "/SearchAnimals;component/Images/animal_yang.jpg";
break;
case "猴 ":
strImage = "/SearchAnimals;component/Images/animal_hou.jpg";
break;
case "雞 ":
strImage = "/SearchAnimals;component/Images/animal_ji.jpg";
break;
case "狗 ":
strImage = "/SearchAnimals;component/Images/animal_gou.jpg";
break;
case "豬 ":
strImage = "/SearchAnimals;component/Images/animal_zhu.jpg";
break;
}
_Animal.Year = year;
_Animal.Name = strName;
_Animal.Image = strImage;
}
private void copy() {
Clipboard.SetText(_Animal.Name);
MessageBox.Show("GongXi , Copy of it Ok!");
}
/// <summary>
/// 通過年份 獲取 生效
/// </summary>
/// <param name="year"></param>
/// <returns></returns>
private String getAnimalNameByYear(int year) {
String name = "";
int initialYear = 1900;
int judgeYear = (year - initialYear) % 12;
switch (judgeYear)
{
case 0:
name = "鼠 ";
break;
case 1:
name = "牛 ";
break;
case 2:
name = "虎 ";
break;
case 3:
name = "兔 ";
break;
case 4:
name = "龍 ";
break;
case 5:
name = "蛇 ";
break;
case 6:
name = "馬 ";
break;
case 7:
name = "羊 ";
break;
case 8:
name = "猴 ";
break;
case 9:
name = "雞 ";
break;
case 10:
name = "狗 ";
break;
case 11:
name = "豬 ";
break;
default:
MessageBox.Show("請重新選擇! ");
break;
}
return name;
}
/// <summary>
/// 初始化 選擇的年份
/// </summary>
/// <returns></returns>
private List<String> initListYear() {
List<String> listyear = new List<string>();
for (int numbers = 2140; numbers >= 1980; numbers--) {
listyear.Add(numbers.ToString());
}
return listyear;
}
/// <summary>
/// 初始化 Animal
/// </summary>
/// <returns></returns>
private AnimalModel initAnimal() {
AnimalModel am = new AnimalModel();
am.Year = "2010";
am.Name = "虎 ";
am.Image = "Images/animal_hu.jpg";
return am;
}
#endregion
/// <summary>
/// AnimalViewModel 構造方法
/// </summary>
public AnimalViewModel() {
_Animal = initAnimal();
_ListYear = initListYear();
}
}
}
運行效果如下: