程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Windows 8 Store Apps學習(55) 綁定: MVVM 模式

Windows 8 Store Apps學習(55) 綁定: MVVM 模式

編輯:關於.NET

介紹

重新想象 Windows 8 Store Apps 之 綁定

通過 MVVM 模式實現數據的添 加、刪除、修改和查詢

示例

1、Model 層

Binding/MVVM/Model/ProductDatabase.cs

/*
 * Model 層的數據持久化操作(本地或遠程)
 * 
 * 本例只是一個演示
 */
    
using System;
using System.Collections.Generic;
using System.Linq;
    
namespace XamlDemo.Binding.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);
        }
    }
}

Binding/MVVM/Model/Product.cs

/*
 * Model 層的實體類,如果需要通知則需要實現 INotifyPropertyChanged 接口
 */
    
using System.ComponentModel;
    
namespace XamlDemo.Binding.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("ProductId");
            }
        }
    
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                RaisePropertyChanged("Name");
            }
        }
    
        private string _category;
        public string Category
        {
            get { return _category; }
            set
            {
                _category = value;
                RaisePropertyChanged("Category");
            }
        }
    
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }
}

2、ViewModel 層

Binding/MVVM/ViewModel/ProductViewModel.cs

/*
 * ViewModel 層
 */
    
using System.Collections.ObjectModel;
using System.Windows.Input;
using XamlDemo.Binding.MVVM.Model;
using System.Linq;
using System.ComponentModel;
    
namespace XamlDemo.Binding.MVVM.ViewModel
{
    public class ProductViewModel
    {
        // 用於提供 Products 數據
        public ObservableCollection<Product> Products { get; set; }
        // 用於“添加”和“查詢”的 Product 對象
        public Product Product { get; set; }
    
        private ProductDatabase _context = null;
    
        public ProductViewModel()
        {
            _context = new ProductDatabase();
    
            Product = new Product();
            Products = new ObservableCollection<Product>();
        }
    
    
        // for 查詢
        public ICommand GetProductsCommand
        {
            get { return new GetProductsCommand(this); }
        }
        public void GetProducts(Product query)
        {
            // 從 Model 獲取數據
            var products = _context.GetProducts(query.Name, query.Category);
    
            // 更新 ViewModel 中的數據
            Products.Clear();
            foreach (var product in products)
            {
                Products.Add(product);
            }
        }
    
    
        // for 添加
        public ICommand AddProductCommand
        {
            get { return new AddProductCommand(this); }
        }
        public void AddProduct(Product product)
        {
            // 更新 Model
            var newProduct = _context.Add(product.Name, product.Category);
    
            // 更新 ViewModel
            Products.Insert(0, newProduct);
        }
    
    
        // for 更新
        public ICommand UpdateProductCommand
        {
            get { return new UpdateProductCommand(this); }
        }
        public void UpdateProduct(Product product)
        {
            // 更新 ViewModel
            product.Name = product.Name + "U";
            product.Category = product.Category + "U";
    
            // 更新 Model
            _context.Update(product);
        }
    
    
        // for 刪除
        public ICommand DeleteProductCommand
        {
            get { return new DeleteProductCommand(this); }
        }
        public void DeleteProduct(Product product)
        {
            // 更新 Model
            _context.Delete(product);
    
            // 更新 ViewModel
            Products.Remove(product);
        }
    }
}

Binding/MVVM/ViewModel/AddProductCommand.cs

/*
 * 添加 Product 數據的 Command
 */
    
using System;
using System.Windows.Input;
    
namespace XamlDemo.Binding.MVVM.ViewModel
{
    public class AddProductCommand : ICommand
    {
        private ProductViewModel _productViewModel;
    
        public AddProductCommand(ProductViewModel productViewModel)
        {
            _productViewModel = productViewModel;
        }
    
        // parameter 是由 ButtonBase 的 CommandParameter 傳遞過來的
        public bool CanExecute(object parameter)
        {
            return true;
        }
    
        // 需要發布此事件的話,在 CanExecute() 方法中調用 OnCanExecuteChanged() 方法即可
        public event EventHandler CanExecuteChanged;
        protected virtual void OnCanExecuteChanged(EventArgs e)
        {
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, e);
        }
    
        // parameter 是由 ButtonBase 的 CommandParameter 傳遞過來的
        public void Execute(object parameter)
        {
            _productViewModel.AddProduct(_productViewModel.Product);
        }
    }
}

Binding/MVVM/ViewModel/DeleteProductCommand.cs

/*
 * 刪除 Product 數據的 Command
 */
    
using System;
using System.Windows.Input;
using XamlDemo.Binding.MVVM.Model;
    
namespace XamlDemo.Binding.MVVM.ViewModel
{
    public class DeleteProductCommand : ICommand
    {
        private ProductViewModel _productViewModel;
    
        public DeleteProductCommand(ProductViewModel productViewModel)
        {
            _productViewModel = productViewModel;
        }
    
        // parameter 是由 ButtonBase 的 CommandParameter 傳遞過來的
        // 當 ButtonBase 的 CommandParameter 中的數據發生變化時,會執行此方法
        // 如果返回 false 則對應的 ButtonBase 將變為不可用
        public bool CanExecute(object parameter)
        {
            var product = (Product)parameter;
            if (product == null)
                return false;
    
            return true;
        }
    
        // 需要發布此事件的話,在 CanExecute() 方法中調用 OnCanExecuteChanged() 

方法即可
        public event EventHandler CanExecuteChanged;
        protected virtual void OnCanExecuteChanged(EventArgs e)
        {
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, e);
        }
    
        // parameter 是由 ButtonBase 的 CommandParameter 傳遞過來的
        public void Execute(object parameter)
        {
            var product = (Product)parameter;
            _productViewModel.DeleteProduct(product);
        }
    }
}

Binding/MVVM/ViewModel/UpdateProductCommand.cs

/*
 * 更新 Product 數據的 Command
 */
    
using System;
using System.Windows.Input;
using XamlDemo.Binding.MVVM.Model;
    
namespace XamlDemo.Binding.MVVM.ViewModel
{
    public class UpdateProductCommand : ICommand
    {
        private ProductViewModel _productViewModel;
    
        public UpdateProductCommand(ProductViewModel productViewModel)
        {
            _productViewModel = productViewModel;
        }
    
        // parameter 是由 ButtonBase 的 CommandParameter 傳遞過來的
        // 當 ButtonBase 的 CommandParameter 中的數據發生變化時,會執行此方法
        // 如果返回 false 則對應的 ButtonBase 將變為不可用
        public bool CanExecute(object parameter)
        {
            var product = (Product)parameter;
            if (product == null)
                return false;
    
            return true;
        }
    
        // 需要發布此事件的話,在 CanExecute() 方法中調用 OnCanExecuteChanged() 

方法即可
        public event EventHandler CanExecuteChanged;
        protected virtual void OnCanExecuteChanged(EventArgs e)
        {
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, e);
        }
    
        // parameter 是由 ButtonBase 的 CommandParameter 傳遞過來的
        public void Execute(object parameter)
        {
            var product = (Product)parameter;
            _productViewModel.UpdateProduct(product);
        }
    }
}

Binding/MVVM/ViewModel/GetProductsCommand.cs

/*
 * 獲取 Product 數據的 Command
 */
    
using System;
using System.Windows.Input;
    
namespace XamlDemo.Binding.MVVM.ViewModel
{
    public class GetProductsCommand : ICommand
    {
        private ProductViewModel _productViewModel;
    
        public GetProductsCommand(ProductViewModel productViewModel)
        {
            _productViewModel = productViewModel;
        }
    
        // parameter 是由 ButtonBase 的 CommandParameter 傳遞過來的
        public bool CanExecute(object parameter)
        {
            return true;
        }
    
        // 需要發布此事件的話,在 CanExecute() 方法中調用 OnCanExecuteChanged() 

方法即可
        public event EventHandler CanExecuteChanged;
        protected virtual void OnCanExecuteChanged(EventArgs e)
        {
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, e);
        }
    
        // parameter 是由 ButtonBase 的 CommandParameter 傳遞過來的
        public void Execute(object parameter)
        {
            _productViewModel.GetProducts(_productViewModel.Product);
        }
    }
}

查看本欄目

3、View 層

Binding/MVVM/Demo.xaml

<Page
    x:Class="XamlDemo.Binding.MVVM.Demo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XamlDemo.Binding.MVVM"
    xmlns:vm="using:XamlDemo.Binding.MVVM.ViewModel"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    
    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">
                
            <!--
                View 層
            -->
                
            <StackPanel.DataContext>
                <vm:ProductViewModel />
            </StackPanel.DataContext>
    
            <ListView Name="listView" ItemsSource="{Binding Products}" Width="300" Height="300" HorizontalAlignment="Left" VerticalAlignment="Top">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock FontSize="14.667" Text="{Binding Name}" 

HorizontalAlignment="Left" />
                            <TextBlock FontSize="14.667" Text="{Binding 

Category}" HorizontalAlignment="Left" Margin="10 0 0 0" />
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
                
            <StackPanel Orientation="Horizontal" Margin="0 10 0 0" 

DataContext="{Binding Product}">
                <TextBlock FontSize="14.667" Text="Name:" 

VerticalAlignment="Center" />
                <TextBox Name="txtName" Text="{Binding Name, Mode=TwoWay}" 

Width="200" />
                <TextBlock FontSize="14.667" Text="Category:" 

VerticalAlignment="Center" Margin="20 0 0 0" />
                <TextBox Name="txtCategory" Text="{Binding Category, 

Mode=TwoWay}" Width="200" />
            </StackPanel>
                
            <!--
                ButtonBase
                    Command - 指定關聯的命令
                    CommandParameter - 傳遞給 Command 的參數
            -->
            <StackPanel Orientation="Horizontal" Margin="0 10 0 0">
                <Button Name="btnSearch" Content="查詢" Command="{Binding 

GetProductsCommand}" Margin="10 0 0 0" />
                <Button Name="btnAdd" Content="添加" Command="{Binding 

AddProductCommand}" Margin="10 0 0 0" />
                <Button Name="btnUpdate" Content="更新" Command="{Binding 

UpdateProductCommand}" CommandParameter="{Binding SelectedItem, 

ElementName=listView}" Margin="10 0 0 0" />
                <Button Name="btnDelete" Content="刪除" Command="{Binding 

DeleteProductCommand}" CommandParameter="{Binding SelectedItem, 

ElementName=listView}" Margin="10 0 0 0" />
            </StackPanel>
                
        </StackPanel>
    </Grid>
</Page>
        
<!--
    另外,MVVM Light Toolkit 是目前比較流行的 MVVM 框架,如果需要全 App 純 MVVM 

的話可以考慮
    在 http://mvvmlight.codeplex.com/ 下載安裝後,手動在安裝目錄的 Vsix 目錄下安

裝相應的 VS 擴展(其中包括 MVVM Light Toolkit 的項目模板)
-->

OK

[源碼下載]:http://files.cnblogs.com/webabcd/Windows8.rar

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved