• WPF简单MVVM实现


    1. MVVM介绍:

        MVVM就是: Model -- 模型(现实中对象的抽象)

                        View -- UI(用户界面)

           ViewModel -- UI界面的抽象(给View提供数据,并响应View的操作)

    2. 关键是要能准确的进行ViewModel的建模,处理好View与ViewModel之间的关系

        2.1. 只有2种关系:

                   数据传递 --- 双向,使用Binding实现;

                   操作传递 --- 单向(只从View传递给ViewModel),使用命令Command实现;

    3. 开始

       3.1. 首先创建NotificationObject,它是所以ViewModel的基类

             因为要使用Binding,而ViewModel就充当数据源的角色,而要实现当值有变化时会自动响应,就必须实现INotifyPropertyChanged接口,代码如下:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.ComponentModel;
     4 using System.Linq;
     5 using System.Text;
     6 using System.Threading.Tasks;
     7 
     8 namespace MVVMTest.ViewModels
     9 {
    10     public class NotificationObject:INotifyPropertyChanged
    11     {
    12         public event PropertyChangedEventHandler PropertyChanged;
    13 
    14         public void RaisePropertyChanged(string property)
    15         {
    16             if (this.PropertyChanged != null)
    17                 this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(property));
    18 
    19         }
    20     }
    21 }
    View Code

       3.2.接着要创建DelegateCommand,实现了ICommand接口,用来处理View发送到ViewModel的命令,代码如下:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Windows.Input;
     7 
     8 namespace MVVMTest.Commands
     9 {
    10     public class DelegateCommand:ICommand
    11     {
    12         public bool CanExecute(object parameter)
    13         {
    14             if (this.CanExecuteFunc == null)
    15             {
    16                 return true;
    17             }
    18 
    19              return this.CanExecuteFunc(parameter);
    20         }
    21 
    22         public event EventHandler CanExecuteChanged;
    23 
    24         public void Execute(object parameter)
    25         {
    26             if (this.ExecuteAction == null)
    27             {
    28                 return;
    29             }
    30             this.ExecuteAction(parameter);
    31         }
    32 
    33         public Action<object> ExecuteAction { get; set; }
    34         public Func<object, bool> CanExecuteFunc { get; set; }
    35     }
    36 }
    View Code

       3.3.为了方便开发,这里推荐自定义一个code snippet(代码块):

            放到此目录下C:Program Files (x86)Microsoft Visual Studio 12.0VC#Snippets1033Visual C#

     1 <?xml version="1.0" encoding="utf-8" ?>
     2 <CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
     3     <CodeSnippet Format="1.0.0">
     4         <Header>
     5             <Title>propn</Title>
     6             <Shortcut>propn</Shortcut>
     7             <Description>Code snippet for NotificationObject property and backing field</Description>
     8             <Author>Microsoft Corporation</Author>
     9             <SnippetTypes>
    10                 <SnippetType>Expansion</SnippetType>
    11             </SnippetTypes>
    12         </Header>
    13         <Snippet>
    14             <Declarations>
    15                 <Literal>
    16                     <ID>type</ID>
    17                     <ToolTip>Property type</ToolTip>
    18                     <Default>int</Default>
    19                 </Literal>
    20                 <Literal>
    21                     <ID>property</ID>
    22                     <ToolTip>Property name</ToolTip>
    23                     <Default>MyProperty</Default>
    24                 </Literal>
    25                 <Literal>
    26                     <ID>field</ID>
    27                     <ToolTip>The variable backing this property</ToolTip>
    28                     <Default>myVar</Default>
    29                 </Literal>
    30             </Declarations>
    31             <Code Language="csharp"><![CDATA[private $type$ $field$;
    32 
    33     public $type$ $property$
    34     {
    35         get { return $field$;}
    36         set {     
    37             $field$ = value;
    38             this.RaisePropertyChanged("$property$");
    39         }
    40     }
    41     $end$]]>
    42             </Code>
    43         </Snippet>
    44     </CodeSnippet>
    45 </CodeSnippets>
    View Code

       3.4. 由于这个例子较简单,所以没有设计到Model的设计,而直接到ViewModel的设计,一般的规则是每个View就有一个对应的ViewModel,而ViewModel是充当View的数据源的,所以只需要考虑View需要什么数据、含有哪些操作,创建MainWindow的ViewModel,MainWindowViewModel,代码如下:

     1 using MVVMTest.Commands;
     2 using System;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 using System.Text;
     6 using System.Threading.Tasks;
     7 
     8 namespace MVVMTest.ViewModels
     9 {
    10     public class MainWindowViewModel:NotificationObject
    11     {
    12         private string txt1;
    13 
    14         public string Txt1
    15         {
    16             get { return txt1; }
    17             set
    18             {
    19                 txt1 = value;
    20                 this.RaisePropertyChanged("Txt1");
    21             }
    22         }
    23 
    24         private string txt2;
    25 
    26         public string Txt2
    27         {
    28             get { return txt2; }
    29             set
    30             {
    31                 txt2 = value;
    32                 this.RaisePropertyChanged("Txt2");
    33             }
    34         }
    35 
    36         private string result;
    37 
    38         public string Result
    39         {
    40             get { return result; }
    41             set
    42             {
    43                 result = value;
    44                 this.RaisePropertyChanged("Result");
    45             }
    46         }
    47 
    48         public DelegateCommand ConcatCommand { get; set; }
    49         public void Concat(object parameter)
    50         {
    51             Result = Txt1 + " and " + Txt2;
    52         }
    53 
    54 
    55         public MainWindowViewModel()
    56         {
    57             ConcatCommand = new DelegateCommand();
    58             ConcatCommand.ExecuteAction = new Action<object>(Concat);
    59         }
    60         
    61         
    62         
    63     }
    64 }
    View Code

        3.4.将ViewModel作为数据源赋值给View的DataContext

     1 using MVVMTest.ViewModels;
     2 using System;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 using System.Text;
     6 using System.Threading.Tasks;
     7 using System.Windows;
     8 using System.Windows.Controls;
     9 using System.Windows.Data;
    10 using System.Windows.Documents;
    11 using System.Windows.Input;
    12 using System.Windows.Media;
    13 using System.Windows.Media.Imaging;
    14 using System.Windows.Navigation;
    15 using System.Windows.Shapes;
    16 
    17 namespace MVVMTest
    18 {
    19     /// <summary>
    20     /// Interaction logic for MainWindow.xaml
    21     /// </summary>
    22     public partial class MainWindow : Window
    23     {
    24         public MainWindow()
    25         {
    26             InitializeComponent();
    27             this.DataContext = new MainWindowViewModel();
    28         }
    29     }
    30 }
    View Code

        3.5.在View中绑定数据:

     1 <Window x:Class="MVVMTest.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         Title="MainWindow" Height="350" Width="525">
     5     <Grid>
     6         <TextBox Margin="40,51,311,216" Text="{Binding Txt1}"/>
     7         <TextBox Margin="230,51,114,216" Text="{Binding Txt2}"/>
     8         <TextBox Margin="128,152,176,139" Text="{Binding Result}"/>
     9         <Button Margin="313,241,64,23" Command="{Binding ConcatCommand}"/>
    10     </Grid>
    11 </Window>
    View Code

    源代码:http://yunpan.cn/c3c7AAXm4U2dP  访问密码 8788

                    

  • 相关阅读:
    overflow :hidden隐藏溢出用处大
    datalist 数据展示顺序
    SEO 特定搜索和外链技巧
    Android网络地址簿同步的方式
    表单全选及取消全选
    for循环的嵌套之小星星。
    数组的方法中那些会改变原数组呢?
    for循环的嵌套之打印倒三角的星星
    Js中的排他思想
    计算阶乘的思路。
  • 原文地址:https://www.cnblogs.com/tommy-huang/p/5015352.html
Copyright © 2020-2023  润新知