背水一战 Windows 10 之 MVVM(Model-View-ViewModel)

  • 通过 x:Bind 实现 MVVM(不用 Command)

示例
1、Model
MVVM/Model/Product.cs

/*
* Model 层的实体类,如果需要通知则需要实现 INotifyPropertyChanged 接口
*/ using System.ComponentModel; namespace Windows10.MVVM.Model
{
public class Product : INotifyPropertyChanged
{
public Product()
{
ProductId = 0;
Name = "";
Category = "";
} private int _productId;
public int ProductId
{
get { return _productId; }
set
{
_productId = value;
RaisePropertyChanged(nameof(ProductId));
}
} private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
RaisePropertyChanged(nameof(Name));
}
} private string _category;
public string Category
{
get { return _category; }
set
{
_category = value;
RaisePropertyChanged(nameof(Category));
}
} public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
}

MVVM/Model/ProductDatabase.cs

/*
* Model 层的数据持久化操作(本地或远程)
*
* 本例只是一个演示
*/ using System;
using System.Collections.Generic;
using System.Linq; namespace Windows10.MVVM.Model
{
public class ProductDatabase
{
private List<Product> _products = null; public List<Product> GetProducts()
{
if (_products == null)
{
Random random = new Random(); _products = new List<Product>(); for (int i = 0; i < 100; i++)
{
_products.Add
(
new Product
{
ProductId = i,
Name = "Name" + i.ToString().PadLeft(4, '0'),
Category = "Category" + (char)random.Next(65, 91)
}
);
}
} return _products;
} public List<Product> GetProducts(string name, string category)
{
return GetProducts().Where(p => p.Name.Contains(name) && p.Category.Contains(category)).ToList();
} public void Update(Product product)
{
var oldProduct = _products.Single(p => p.ProductId == product.ProductId);
oldProduct = product;
} public Product Add(string name, string category)
{
Product product = new Product();
product.ProductId = _products.Max(p => p.ProductId) + 1;
product.Name = name;
product.Category = category; _products.Insert(0, product); return product;
} public void Delete(Product product)
{
_products.Remove(product);
}
}
}

2、ViewModel
MVVM/ViewModel2/ProductViewModel.cs

/*
* ViewModel 层
*/ using System.Collections.ObjectModel;
using System.ComponentModel;
using Windows.UI.Xaml;
using Windows10.MVVM.Model; namespace Windows10.MVVM.ViewModel2
{
public class ProductViewModel : INotifyPropertyChanged
{
// 用于提供 Products 数据
private ObservableCollection<Product> _products;
public ObservableCollection<Product> Products
{
get { return _products; }
set
{
_products = value;
RaisePropertyChanged(nameof(Products));
}
} // 用于“添加”和“查询”的 Product 对象
private Product _product;
public Product Product
{
get { return _product; }
set
{
_product = value;
RaisePropertyChanged(nameof(Product));
}
} // 数据库对象
private ProductDatabase _context = null; public ProductViewModel()
{
_context = new ProductDatabase(); Product = new Product();
Products = new ObservableCollection<Product>(_context.GetProducts());
} public void GetProducts(object sender, RoutedEventArgs e)
{
// 从 Model 层获取数据
Products = new ObservableCollection<Product>(_context.GetProducts(Product.Name, Product.Category));
} public void AddProduct(object sender, RoutedEventArgs e)
{
// 在 Model 层添加一条数据
Product newProduct = _context.Add(Product.Name, Product.Category); // 更新 ViewModel 层数据
Products.Insert(0, newProduct);
} public void UpdateProduct(object sender, RoutedEventArgs e)
{
Product product = ((FrameworkElement)sender).Tag as Product; // 更新 ViewModel 层数据
product.Name = product.Name + "U";
product.Category = product.Category + "U"; // 更新 Model 层数据
_context.Update(product);
} public void DeleteProduct(object sender, RoutedEventArgs e)
{
Product product = ((FrameworkElement)sender).Tag as Product; // 更新 Model 层数据
_context.Delete(product); // 更新 ViewModel 层数据
Products.Remove(product);
} public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
}

3、View
MVVM/View/Demo2.xaml

<Page
x:Class="Windows10.MVVM.View.Demo2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.MVVM.View"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" xmlns:model="using:Windows10.MVVM.Model"> <Grid Background="Transparent">
<StackPanel Margin="10 0 10 10"> <!--
View 层
--> <!--
本例通过 x:Bind 实现 MVVM(不用 Command)
--> <ListView Name="listView" ItemsSource="{x:Bind ProductViewModel.Products, Mode=OneWay}" Width="300" Height="300" HorizontalAlignment="Left" VerticalAlignment="Top">
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:Product">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{x:Bind Name, Mode=OneWay}" HorizontalAlignment="Left" />
<TextBlock Text="{x:Bind Category, Mode=OneWay}" HorizontalAlignment="Left" Margin="10 0 0 0" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView> <StackPanel Orientation="Horizontal" Margin="0 10 0 0">
<TextBlock Text="Name:" VerticalAlignment="Center" />
<TextBox Name="txtName" Text="{x:Bind ProductViewModel.Product.Name, Mode=TwoWay}" Width="100" />
<TextBlock Text="Category:" VerticalAlignment="Center" Margin="20 0 0 0" />
<TextBox Name="txtCategory" Text="{x:Bind ProductViewModel.Product.Category, Mode=TwoWay}" Width="100" />
</StackPanel> <StackPanel Orientation="Horizontal" Margin="0 10 0 0">
<Button Name="btnSearch" Content="查询" Click="{x:Bind ProductViewModel.GetProducts}" Margin="10 0 0 0" />
<Button Name="btnAdd" Content="添加" Click="{x:Bind ProductViewModel.AddProduct}" Margin="10 0 0 0" />
<Button Name="btnUpdate" Content="更新" Click="{x:Bind ProductViewModel.UpdateProduct}" Tag="{x:Bind listView.SelectedItem, Mode=OneWay}" Margin="10 0 0 0" />
<Button Name="btnDelete" Content="删除" Click="{x:Bind ProductViewModel.DeleteProduct}" Tag="{x:Bind listView.SelectedItem, Mode=OneWay}" Margin="10 0 0 0" />
</StackPanel> </StackPanel>
</Grid>
</Page>

MVVM: 通过 x:Bind 实现 MVVM(不用 Command)的更多相关文章

  1. 背水一战 Windows 10 (25) - MVVM: 通过 x:Bind 实现 MVVM(不用 Command)

    [源码下载] 背水一战 Windows 10 (25) - MVVM: 通过 x:Bind 实现 MVVM(不用 Command) 作者:webabcd 介绍背水一战 Windows 10 之 MVV ...

  2. WPF/MVVM Quick Start Tutorial - WPF/MVVM 快速入门教程 -原文,翻译及一点自己的补充

    转载自 https://www.codeproject.com/articles/165368/wpf-mvvm-quick-start-tutorial WPF/MVVM Quick Start T ...

  3. 【MVVM Light】新手初识MVVM,你一看就会

    一.前言 作为一个初入软件业的新手,各种设计模式与框架对我是眼花缭乱的.所以当我接触到这些新知识的时候就希望自己能总结几个步骤,以便更好更方便的在日常工作中进行使用. MVVM顾名思义就是Model- ...

  4. MVVM模式应用 之为ApplicationBarIconButton 添加Command操作属性

    在学习MVVM的过程中,总是会遇到挫折,一碰到就是花费好长时间去解决..唉,不求量,只求质. 第一种(已经实践成功): (1)http://bindableapplicationb.codeplex. ...

  5. MVVM开发模式简单实例MVVM Demo

    本文主要是翻译Rachel Lim的一篇有关MVVM模式介绍的博文 A Simple MVVM Example 并具体给出了一个简单的Demo(原文是以WPF开发的,对于我自己添加或修改的一部分会用红 ...

  6. MVVM开发模式简单实例MVVM Demo【续】

    本文将接着上篇文章,介绍一下三点:(Universal App) 1.将添加Product集合,绑定到列表 2.给点击ListBox的添加选项改变时的事件(要附加依赖属性,和Button点击事件不同) ...

  7. MVVM大比拼之avalon.js源码精析

    简介 avalon是国内 司徒正美 写的MVVM框架,相比同类框架它的特点是: 使用 observe 模式,性能高. 将原始对象用object.defineProperty重写,不需要用户像用knoc ...

  8. WPF自定义控件与样式(14)-轻量MVVM模式实践

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. MVVM是WPF中一个非 ...

  9. A Simple MVVM Example[Forward]

    In my opinion, if you are using WPF or Silverlight you should be using the MVVM design pattern. It i ...

随机推荐

  1. 理解Java中字符流与字节流的区别

    1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个“流动的方向”,通常可以从中读入一个字节序 ...

  2. 一个简单的socket程序运行与抓包查看

    为了熟悉socket编程,在ubuntu下运行了一个现有例子(Networking and Socket programming tutorial in C - CodeProject),并通过抓包查 ...

  3. Linux—C内存管理

    程序(可执行文件)存储结构与进程存储结构: 查看文件基本情况:file fileName.查看文件存储情况:size fileName(代码区text segment.全局初始化/静态数据区data ...

  4. EF的入门使用 (电影管理)

    控制器代码: public class HomeController : Controller { private NewDBContext ndc = new NewDBContext(); pub ...

  5. NPM 如何升级?

  6. PHP中$_SERVER的详细参数与说明

    $_SERVER['PHP_SELF'] #当前正在执行脚本的文件名,与 document root相关. $_SERVER['argv'] #传递给该脚本的参数. $_SERVER['argc'] ...

  7. 准备NOIP2017 最长公共子序列(模版)

    一些概念: (1)子序列: 一个序列A = a1,a2,--an,中任意删除若干项,剩余的序列叫做A的一个子序列.也可以认为是从序列A按原顺序保留任意若干项得到的序列.例如:   对序列 1,3,5, ...

  8. android 获取当前系统时间

    取得系统时间 1. long time=System.currentTimeMillis(); 2. final Calendar mCalendar=Calendar.getInstance(); ...

  9. hadoop: hdfs API示例

    利用hdfs的api,可以实现向hdfs的文件.目录读写,利用这一套API可以设计一个简易的山寨版云盘,见下图: 为了方便操作,将常用的文件读写操作封装了一个工具类: import org.apach ...

  10. 如何在前台脚本通过json传递数据到后台(使用微软自带的ajax)

    首先,我们要在前台引入json的脚本,以便于把js对象序列化 <script type="text/javascript" src="/js/jquery.json ...