WPF MVVM模式构建项目

什么是MVVM模式?

        MVVM是Model-View-ViewModel的简写,Model就是模型,View就是视图,ViewModel就是View和Model之间解耦和传递消息的中间层。MVVM采用双向数据绑定,View中数据变化将自动反映到ViewModel上,反之,Model中数据变化也将会自动展示在View上。通过MVVM模式使得View和Model上的修改相互不影响,方便程序分工,测试和维护。

        基于WPF的MVVM模式的框架有很多种,流行的是MvvmLight(轻量级Mvvm框架,现已不更新)和Prism(大型Mvvm框架),本篇不使用框架来实现MVVM模式构建项目,了解WPF内部实现机理。使用MVVM框架请参考:

MvvmLight:WPF MVVMLight介绍和使用(1)_无熵~的博客-CSDN博客

Prism:WPF Prism介绍和简单实例_prism.wpf_无熵~的博客-CSDN博客

创建一个基于MVVM模式的登录项目,实现方式:
        首先建立相应的文件夹:一个ViewModel,一个View,一个Model。在ViewModel里面有一个基础的通知类:NotifyPropertyChanged,这个类继承自INotifyPropertyChanged(这个类是通知的基础类,当事件执行时,会将相应的值显示在绑定的控件上);一个命令通知类:DelegateCommand,实现ICommand接口,用于消息传递。

 Model类:如果想让属性绑定到其他数据,可以将属性定义成依赖属性并让类继承DependencyObject类。

    public class User:DependencyObject
    {
        public string Name
        {
            get { return (string)GetValue(NameProperty); }
            set { SetValue(NameProperty, value); }
        }
        // Using a DependencyProperty as the backing store for Name.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NameProperty =
            DependencyProperty.Register("Name", typeof(string), typeof(User), new PropertyMetadata(null));

        public string Password
        {
            get { return (string)GetValue(PasswordProperty); }
            set { SetValue(PasswordProperty, value); }
        }
        public static readonly DependencyProperty PasswordProperty =
            DependencyProperty.Register("Password", typeof(string), typeof(User), new PropertyMetadata(null));
    }

View页面实现:

<Window x:Class="WpfMvvmDemo.View.LoginWindow"
        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:WpfMvvmDemo.View"
        mc:Ignorable="d"
        Title="{Binding Info}" Height="450" Width="800" WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBox x:Name="txtUser" Text="{Binding User.Name,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
                  Width="300" Height="40"/>
        <TextBox x:Name="txtPassword" Text="{Binding User.Password,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
                 Grid.Row="1" Width="300" Height="40" />
        <Button  Content="Query" Command="{Binding LoginCommand}" CommandParameter="login"
                 Grid.Row="2"  Width="200" Height="30"  />
    </Grid>
</Window>

View页面指定数据源:

    /// <summary>
    /// LoginWindow.xaml 的交互逻辑
    /// </summary>
    public partial class LoginWindow : Window
    {
        public LoginWindow()
        {
            InitializeComponent();
            this.DataContext = new UserVM();
        }
    }

ViewModel类:

    public class UserVM: NotifyPropertyChanged
    {

        private string info;

        public string Info
        {
            get { return info; }
            set
            {
                info = value;
                OnPropertyChanged();
            }
        }

        public UserVM()
        {
            User = new User()
            {
                Name = "admin",
                Password = "123456"
            };
            Info = "用户登录";
        }

        private User user;

        public User User
        {
            get { return user; }
            set
            {
                user = value;
                OnPropertyChanged();
                //NotifyPropertyChanged("User");
            }
        }
        public ICommand LoginCommand
        {
            get { return new DelegateCommand(LoginCommandEvent, CanLogin); }
        }

        private void LoginCommandEvent(Object o)
        {
            MessageBox.Show(string.Format($"用户:{User.Name},参数:{o.ToString()}"));
        }

        private bool CanLogin(Object o)
        {
            if(o!=null)
            {
                return true;
            }
            return false;
        }
    }

ViewModel中NotifyPropertyChanged类定义,继承自INotifyPropertyChanged。

    public class NotifyPropertyChanged : INotifyPropertyChanged
    {
        /// <summary>
        /// 实现接口
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 属性变更事件
        /// </summary>
        /// <param name="Path">事件源</param>
        public void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

ViewModel中DelegateCommand类定义,实现ICommand接口。

    public class DelegateCommand : ICommand
    {
        public event EventHandler CanExecuteChanged
        {
            add
            {
                if (_canExecute != null)
                {
                    CommandManager.RequerySuggested += value;
                }
            }
            remove
            {
                if (_canExecute != null)
                {
                    CommandManager.RequerySuggested -= value;
                }
            }
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute == null)
            {
                return true;
            }
            return _canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            if (_execute != null && CanExecute(parameter))
            {
                _execute(parameter);
            }
        }

        private Func<object, bool> _canExecute;
        private Action<object> _execute;

        public DelegateCommand(Action<object> execute, Func<object, bool> canExecute)
        {
            _execute = execute;
            _canExecute = canExecute;
        }
 
        public DelegateCommand(Action<object> execute) :
            this(execute, null)
        {
        }

    }

实例链接:https://download.csdn.net/download/lvxingzhe3/87669239

猜你喜欢

转载自blog.csdn.net/lvxingzhe3/article/details/130040460