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

Posted ansen312

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MVVM: 通过 x:Bind 实现 MVVM(不用 Command)相关的知识,希望对你有一定的参考价值。

背水一战 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)的主要内容,如果未能解决你的问题,请参考以下文章

MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令

MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令

Vue之九数据劫持实现MVVM的数据双向绑定

Vue.js 是如何实现 MVVM 的?

wpf MVVM框架基础

MVVM简介