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

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

[源码下载]

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

作者:webabcd

介绍
背水一战 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>

OK
[源码下载]

时间: 2024-11-16 11:02:20

背水一战 Windows 10 (25) - MVVM: 通过 x:Bind 实现 MVVM(不用 Command)的相关文章

背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令

原文:背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令 [源码下载] 背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令 作者:webabcd 介绍背水一战 Windows 10 之 MVVM(Model-View-ViewModel) 通过 Binding 或 x:Bin

背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令

原文:背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令 [源码下载] 背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令 作者:webabcd 介绍背水一战 Windows 10 之 MVVM(Model-View-ViewModel) 通过 Binding 或 x:B

背水一战 Windows 10 (21) - 绑定: x:Bind 绑定, x:Bind 绑定之 x:Phase, 使用绑定过程中的一些技巧

原文:背水一战 Windows 10 (21) - 绑定: x:Bind 绑定, x:Bind 绑定之 x:Phase, 使用绑定过程中的一些技巧 [源码下载] 背水一战 Windows 10 (21) - 绑定: x:Bind 绑定, x:Bind 绑定之 x:Phase, 使用绑定过程中的一些技巧 作者:webabcd 介绍背水一战 Windows 10 之 绑定 x:Bind 绑定 x:Bind 绑定之 x:Phase 使用绑定过程中的一些技巧 示例1.演示 x:Bind 绑定的相关知识点

背水一战 Windows 10 (26) - XAML: x:DeferLoadStrategy, x:Null

原文:背水一战 Windows 10 (26) - XAML: x:DeferLoadStrategy, x:Null [源码下载] 背水一战 Windows 10 (26) - XAML: x:DeferLoadStrategy, x:Null 作者:webabcd 介绍背水一战 Windows 10 之 XAML x:DeferLoadStrategy="Lazy" - 用于指定一个 UIElement 为一个延迟加载元素 x:Null - null 示例1.x:DeferLoad

背水一战 Windows 10 (53) - 控件(集合类): ItemsControl 的布局控件 - ItemsStackPanel, ItemsWrapGrid

原文:背水一战 Windows 10 (53) - 控件(集合类): ItemsControl 的布局控件 - ItemsStackPanel, ItemsWrapGrid [源码下载] 背水一战 Windows 10 (53) - 控件(集合类): ItemsControl 的布局控件 - ItemsStackPanel, ItemsWrapGrid 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合类 - ItemsControl 的布局控件) ItemsStackPa

背水一战 Windows 10 (54) - 控件(集合类): ItemsControl 的布局控件 - OrientedVirtualizingPanel, VirtualizingStackPanel, WrapGrid

原文:背水一战 Windows 10 (54) - 控件(集合类): ItemsControl 的布局控件 - OrientedVirtualizingPanel, VirtualizingStackPanel, WrapGrid [源码下载] 背水一战 Windows 10 (54) - 控件(集合类): ItemsControl 的布局控件 - OrientedVirtualizingPanel, VirtualizingStackPanel, WrapGrid 作者:webabcd 介绍背

背水一战 Windows 10 (39) - 控件(布局类): VariableSizedWrapGrid, Border, Viewbox, SplitView

原文:背水一战 Windows 10 (39) - 控件(布局类): VariableSizedWrapGrid, Border, Viewbox, SplitView [源码下载] 背水一战 Windows 10 (39) - 控件(布局类): VariableSizedWrapGrid, Border, Viewbox, SplitView 作者:webabcd 介绍背水一战 Windows 10 之 控件(布局类) VariableSizedWrapGrid Border Viewbox

背水一战 Windows 10 (45) - 控件(图标类): IconElement, SymbolIcon, FontIcon, PathIcon, BitmapIcon

原文:背水一战 Windows 10 (45) - 控件(图标类): IconElement, SymbolIcon, FontIcon, PathIcon, BitmapIcon [源码下载] 背水一战 Windows 10 (45) - 控件(图标类): IconElement, SymbolIcon, FontIcon, PathIcon, BitmapIcon 作者:webabcd 介绍背水一战 Windows 10 之 控件(图标类) IconElement SymbolIcon Fo

背水一战 Windows 10 (33) - 控件(选择类): ListBox, RadioButton, CheckBox, ToggleSwitch

原文:背水一战 Windows 10 (33) - 控件(选择类): ListBox, RadioButton, CheckBox, ToggleSwitch [源码下载] 背水一战 Windows 10 (33) - 控件(选择类): ListBox, RadioButton, CheckBox, ToggleSwitch 作者:webabcd 介绍背水一战 Windows 10 之 控件(选择类) ListBox RadioButton CheckBox ToggleSwitch 示例1.L