【MVVM】WPF

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/j15533415886/article/details/80563787

一、新建WPF Demo
这里写图片描述

添加一个Student类,代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;// INotifyPropertyChanged

namespace MVVMDemo
{
    public class Student: INotifyPropertyChanged
    {
        string firstName;
        public string FirstName
        {
            get
            {
                return firstName;
            }
            set
            {
                firstName = value;
                OnPropertyChanged("FirstName");
            }
        }

        string lastName;
        public string LastName
        {
            get
            {
                return lastName;
            }
            set
            {
                lastName = value;
                OnPropertyChanged("LastName");
            }
        }

        public Student(string firstName, string lastName)
        {
            this.firstName = firstName;
            this.lastName = lastName;
        }


        void OnPropertyChanged(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

        #region INotifyPropertyChanged Members  
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }
}

这里写图片描述

修改MainWindow.xaml,代码如下

<Window x:Class="MVVMDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MVVMDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid x:Name="gridLayout">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="5*"/>
            <ColumnDefinition Width="5*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="5*"/>
            <RowDefinition Height="5*"/>
            <RowDefinition Height="5*"/>
            <RowDefinition Height="5*"/>
        </Grid.RowDefinitions>

        <TextBlock Text="FirstName:" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBlock Text="{Binding Path=FirstName,Mode=TwoWay}" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"/>
        <TextBlock Text="LastName:" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBox Text="{Binding Path=LastName,Mode=TwoWay}" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"/>
        <Button x:Name="BtnView" Content="I am View" Grid.Row="2" Grid.Column="0" Width="150" Height="50" VerticalAlignment="Center" HorizontalAlignment="Right"/>
    </Grid>
</Window>

MainWindow视图
这里写图片描述

在MainWindow.xaml.cs添加以下代码

 public MainWindow()
        {
            InitializeComponent();
            Student student = new Student("Wang","WenSong");
            gridLayout.DataContext = student;
            BtnView.Click += new RoutedEventHandler(delegate (object sender, RoutedEventArgs e)
            {
                student.FirstName = "BBK工作室";
                student.LastName = "www.bigbearking.com";
            });
        }

点击“I am View” Button按钮,运行程序,如下图
这里写图片描述

新建一个超类
这里写图片描述

NotificationObject.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using System.Linq.Expressions;

namespace MVVMDemo
{
    public abstract class NotificationObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        protected void RaisePropertyChanged(params string[] propertyNames)
        {
            if (propertyNames == null) throw new ArgumentNullException("propertyNames");

            foreach (var name in propertyNames)
            {
                this.RaisePropertyChanged(name);
            }
        }

        protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
        {
            var propertyName = ExtractPropertyName(propertyExpression);
            this.RaisePropertyChanged(propertyName);
        }

        public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
        {
            if (propertyExpression == null)
            {
                throw new ArgumentNullException("propertyExpression");
            }

            var memberExpression = propertyExpression.Body as MemberExpression;
            if (memberExpression == null)
            {
                throw new ArgumentException("PropertySupport_NotMemberAccessExpression_Exception", "propertyExpression");
            }

            var property = memberExpression.Member as PropertyInfo;
            if (property == null)
            {
                throw new ArgumentException("PropertySupport_ExpressionNotProperty_Exception", "propertyExpression");
            }

            var getMethod = property.GetGetMethod(true);
            if (getMethod.IsStatic)
            {
                throw new ArgumentException("PropertySupport_StaticExpression_Exception", "propertyExpression");
            }

            return memberExpression.Member.Name;
        }

    }
}

修改student.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;// INotifyPropertyChanged

namespace MVVMDemo
{
    public class Student: NotificationObject
    {
        string firstName;
        public string FirstName
        {
            get
            {
                return firstName;
            }
            set
            {
                firstName = value;
                //OnPropertyChanged("FirstName");
                this.RaisePropertyChanged("LastName");
            }
        }

        string lastName;
        public string LastName
        {
            get
            {
                return lastName;
            }
            set
            {
                lastName = value;
                //OnPropertyChanged("LastName");
                this.RaisePropertyChanged("LastName");
            }
        }

        public Student(string firstName, string lastName)
        {
            this.firstName = firstName;
            this.lastName = lastName;
        }


        void OnPropertyChanged(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

        #region INotifyPropertyChanged Members  
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }
}

二、建立MVVM的各个部分
在WPF工程上建立 Model、View、ViewModel 三个文件夹
这里写图片描述
1. 将Student.cs移到Model文件夹内,并修改Student.cs里的代码,修改后的Student.cs内容如下(注意命名空间的变化)
Student.cs

using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;  

namespace MVVMDemo.Model  
{  
    public class Student  
    {  
        string firstName;  
        public string FirstName  
        {  
            get  
            {  
                return firstName;  
            }  
            set  
            {  
                firstName = value;  
            }  
        }  

        string lastName;  
        public string LastName  
        {  
            get  
            {  
                return lastName;  
            }  
            set  
            {  
                lastName = value;  
            }     
        }  

        public Student()  
        {  
            //模拟获取数据  
            //这里为什么会有模拟数据一说呢?我是这样认为的,有时候类的属性会存在数据库或者本地文件系统等上面,  
            //我们需要读取操作将这些数据加载到咱们定义的类里。  
            Mock();  
        }  

        public void Mock()  
        {  
            FirstName = "firstName:" + DateTime.Now.ToString();  
            LastName = "lastName:" + DateTime.Now.ToString();  
        }  


    }  
}  

工程结构图
这里写图片描述

2.在ViewModel文件夹右击添加一个StudentViewModel类
StudentViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MVVMDemo.Model;

namespace MVVMDemo.ViewModel
{
    public class StudentViewModel:NotificationObject
    {
        private Student student;
        public Student Student
        {
            get
            {
                return this.student;
            }
            set
            {
                this.student = value;
                //下面这一句话的用法以后再拿出一章具体介绍  
                this.RaisePropertyChanged(() => this.student);
            }
        }
        public StudentViewModel()
        {
            student = new Student();
        }
    }
}

工程结构图
这里写图片描述

3.在View文件夹下添加一个用户控件,命名为StudentView。
StudentView.xaml

<UserControl x:Class="MVVMDemo.View.StudentView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MVVMDemo.View"
             xmlns:vm="clr-namespace:MVVMDemo.ViewModel"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid x:Name="gridLayout">
        <Grid.DataContext>
            <vm:StudentViewModel />
        </Grid.DataContext>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="5*" />
            <ColumnDefinition Width="5*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="5*" />
            <RowDefinition Height="5*" />
            <RowDefinition Height="5*" />
            <RowDefinition Height="5*" />
        </Grid.RowDefinitions>

        <TextBlock Text="FirstName:" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBlock Text="{Binding Path=Student.FirstName,Mode=Default}" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"/>
        <TextBlock Text="LastName:" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBox Text="{Binding Path=Student.LastName,Mode=TwoWay}" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"/>
        <Button x:Name="BtnView" Content="I am View" Grid.Row="2" Grid.Column="0" Width="150" Height="50" VerticalAlignment="Center" HorizontalAlignment="Right"/>

    </Grid>
</UserControl>

工程结构图
这里写图片描述
然后在MainWindow里需要引用这个控件,修改MainWindow.xaml的代码

<Window x:Class="MVVMDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:view="clr-namespace:MVVMDemo.View" 
        Title="MainWindow" Height="350" Width="525">
    <Grid x:Name="gridLayout">
        <view:StudentView />
    </Grid>
</Window>

再将MainWindow.cs里之前添加的代码删掉,修改后的内容如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MVVMDemo
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

运行程序,效果图如下
这里写图片描述

猜你喜欢

转载自blog.csdn.net/j15533415886/article/details/80563787