WPF MVVM
创始人
2024-02-01 01:17:24
0

WPF MVVM

MVVM=Model+View+ViewModel

  • Model:现实世界中对象抽象的结果,也就是实体模型
  • View:UI界面
  • ViewModel:为UI界面服务的模型,可以理解为数据传输对象(DTO)
    ViewModel和View的沟通有两个方面:数据和操作
  • 传递数据–使用数据属性
  • 传递操作–使用命令属性
    在这里插入图片描述

案例1:

关注点:NotificationObject与数据属性
DelegateCommand与命令属性
在这里插入图片描述

命令的传递(单向)

class DelegateCommand : ICommand
{public bool CanExecute(object parameter){if (this.CanExecuteFunc == null){return true;}return this.CanExecuteFunc(parameter);}public event EventHandler CanExecuteChanged;public void Execute(object parameter){if (this.ExecuteAction == null){return;}this.ExecuteAction(parameter);}public Action ExecuteAction { get; set; }public Func CanExecuteFunc { get; set; }
}
 

ViewModels

//通知Binding属性更新,供ViewModels使用的类
class NotificationObject : INotifyPropertyChanged
{public event PropertyChangedEventHandler PropertyChanged;public void RaisePropertyChanged(string propertyName){if (this.PropertyChanged != null){this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));}}
}

该案例只有一个MainWindow,所以创建一个MainWindowViewModel类

class MainWindowViewModel : NotificationObject
{private double input1;public double Input1{get { return input1; }set{input1 = value;this.RaisePropertyChanged("Input1");}}private double input2;public double Input2{get { return input2; }set{input2 = value;this.RaisePropertyChanged("Input2");}}private double result;public double Result{get { return result; }set{result = value;this.RaisePropertyChanged("Result");}}public DelegateCommand AddCommand { get; set; }public DelegateCommand SaveCommand { get; set; }private void Add(object parameter){this.Result = this.Input1 + this.Input2;}private void Save(object parameter){SaveFileDialog dlg = new SaveFileDialog();dlg.ShowDialog();}public MainWindowViewModel(){this.AddCommand = new DelegateCommand();this.AddCommand.ExecuteAction = new Action(this.Add);this.SaveCommand = new DelegateCommand();this.SaveCommand.ExecuteAction = new Action(this.Save);}
}
 

主界面

由于Binding不指定Source默认使用了控件的DataContext,所以只需要在MainWindow中增加DataContext,子代控件便可以共享这个DataContext。

public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();this.DataContext = new MainWindowViewModel();}
}

案例2:

在这里插入图片描述

项目使用了Microsoft.Practices.Prism,需要提前引用

  • Models

要显示单品和饭店信息,所以定义Dish和Restaurant两个类

public class Dish : NotificationObject
{public string Name { get; set; }public string Category { get; set; }public string Comment { get; set; }public double Score { get; set; }
}
class Restaurant : NotificationObject
{public string Name { get; set; }public string Address { get; set; }public string PhoneNumber { get; set; }
}
  • Services

具有获得菜单和点单服务,先定义相关接口,再实现类

public interface IDataService
{List GetAllDishes();
}
class XmlDataService : IDataService
{public List GetAllDishes(){List dishList = new List();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);dishList.Add(dish);}return dishList;}
}
interface IOrderService
{void PlaceOrder(List dishes);
}
class MockOrderService : IOrderService
{public void PlaceOrder(List dishes){System.IO.File.WriteAllLines(@"C:\Users\cni23287938\Desktop\orders.txt", dishes.ToArray());}
}
  • ViewModels

因为菜单后面需要具有一个是否选择项,所以要新定义一个DishMenuItemViewModel类

class DishMenuItemViewModel : NotificationObject
{public Dish Dish { get; set; }private bool isSelected;public bool IsSelected{get { return isSelected; }set{isSelected = value;this.RaisePropertyChanged("IsSelected");}}
}

MainWindowViewModel

class MainWindowViewModel : NotificationObject
{private int count;public int Count{get { return count; }set { count = value; this.RaisePropertyChanged("Count"); }}private Restaurant restaurant;public Restaurant Restaurant{get { return restaurant; }set { restaurant = value; this.RaisePropertyChanged("restaurant"); }}private List dishMenu;public List DishMenu{get { return dishMenu; }set { dishMenu = value; this.RaisePropertyChanged("DishMenu"); }}public DelegateCommand PlaceOrderCommand { get; set; }public DelegateCommand SelectMenuItemCommand { get; set; }public MainWindowViewModel(){LoadRestaurant();LoadDishMenu();PlaceOrderCommand = new DelegateCommand(this.PlaceOrderCommandExecute);SelectMenuItemCommand = new DelegateCommand(this.SelectMenuItemExecute);}private void LoadRestaurant(){this.Restaurant = new Restaurant();this.Restaurant.Name = "Crazy";this.restaurant.Address = "北京";this.restaurant.PhoneNumber = "1";}private void LoadDishMenu(){IDataService ds = new XmlDataService();var dishes = ds.GetAllDishes();this.dishMenu = new List();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(){Count = DishMenu.Count(i => i.IsSelected == true);}
}

xaml

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...