wpf--->MVVM

MVVM适合制作企业级的应用

MVVM优势

  1. 团队层面:统一团队的思维方式和实现方法(特定的代码放在特定的位置)
  2. 架构层面:稳定,解耦合
  3. 代码层面:可读,可测,可替换

什么是MVVM

  • MVVM= Model + View + ViewModel
    在这里插入图片描述

Model

  • 现实中的抽象结果

View&ViewModel

  • View=UI
  • ViewModel=Model for View
  • ViewModel与View之间的沟通
    1. 数据属性—传递数据,双向的数据属性
    2. 命令属性—传递操作,单向的命令属性
NotificationObject与数据属性
DelegateCommand与命令属性

使用实例

1. 首先需要建立几个文件夹

在这里插入图片描述

2. 实现ViewModel的基类

NotificationObject.cs数据属性Binding实现
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Linq;
	using System.Text;
	using System.Threading.Tasks;
	
	namespace MyControlDemo.ViewModels
	{
	    class NotificationObject : INotifyPropertyChanged
	    {
	        //属性发生变化时,PropertyChanged事件会被双向数据Binding监听,
	        //一旦发生变化,变化的值会被送到界面上去
	        public event PropertyChangedEventHandler PropertyChanged;
	
	        //对事件进行一个简单的封装
	        public void RaisePropertyChange(string propertyName)
	        {
	            if (this.PropertyChanged != null)
	            {
	                //告诉Binding哪个属性发生了变化
	                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
	            }
	        }
	    }
	}
DelegateCommand命令属性Binding
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace MyControlDemo.Commands
{
    class DelegateCommand : ICommand
    {
        //当命令是否能执行状态发生改变,会通知命令调用者,状态发生了改变
        public event EventHandler CanExecuteChanged;

        //CanExecute帮助命令的呼叫者,判断该命令是否可以执行
        public bool CanExecute(object parameter)
        {
            if (this.CanExecuteFunc == null)
                return true;
            return this.CanExecuteFunc(parameter);
        }

        //当命令执行的时候,想要执行什么内容,将内容写在Execute中
        public void Execute(object parameter)
        {
            if (this.ExecuteAction == null)
                return;
            //当命令执行时,执行ExecuteAction委托
            this.ExecuteAction(parameter);
        }

        //声明一个Action类型的委托
        public Action<Object> ExecuteAction { get; set; }
        public Func<object, bool> CanExecuteFunc { get; set; }
    }
}

3.实现MainWindow的ViewModel

  1. 在ViewModel文件夹下创建MainWindowViewModel.cs类
  2. 继承实现的数据属性Binding类NotificationObject(所有ViewModel的基类)
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using MyControlDemo.Commands;
    
    namespace MyControlDemo.ViewModels
    {
        class MainWindowViewModel : NotificationObject
        {
            private double input1;
    
            public double Input1
            {
                get { return input1; }
                set
                {
                    input1 = value;
                    this.RaisePropertyChange("Input1");
                }
            }
    
            private double input2;
    
            public double Input2
    
            {
                get { return input2; }
                set
                {
                    input2 = value;
                    this.RaisePropertyChange("Input2");
                }
            }
    
            private double result;
    
            public double Result
            {
                get { return result; }
                set
                {
                    result = value;
                    this.RaisePropertyChange("Result");
                }
            }
    
            //命令属性,引入重写的ICommand,也就是DelegateCommand的命名空间
            public DelegateCommand AddCommand { get; set; }
    
            private void Add(Object parameter)
            {
                //当result值发生改变,会调用属性set中的RaisePropertyChange,
                //值发生变化会被事件检测到,并反馈到界面上去
                this.result = this.input1 + this.input2;
            }
    
            public MainWindowViewModel()
            {
                //将命令属性与方法关联
                this.AddCommand =new DelegateCommand();
                this.AddCommand.ExecuteAction = new Action<object>(this.Add);
            }
        }
    }
    

4.Binding控件与属性

<Window x:Class="WpfApp1.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:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="200">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <TextBox x:Name="tb1" Grid.Row="1" Height="30" Width="100" Background="LightBlue" Margin="5" Text="{Binding Input1}"/>
            <TextBox x:Name="tb2" Grid.Row="2" Height="30" Width="100" Background="LightBlue" Margin="5" Text="{Binding Input2}"/>
            <TextBox x:Name="tb3" Grid.Row="3" Height="30" Width="100" Background="LightBlue" Margin="5" Text="{Binding Result}"/>
            <Button x:Name="b1" Grid.Row="4"  Height="20" Width="30" Content="Add" Command="{Binding AddCommand}"/>
        </Grid>
    </Grid>
</Window>

5.使用DataContext绑定定义一个源

DataContext
MainWindow.xaml.cs

 this.DataContext = new MainWindowViewModel();
WPF MVVM 架构中,可以使用 InvokeCommandAction 来触发 ViewModel 中的命令,并且可以传递一个参数。如果需要传递多个参数,可以使用以下方法: 1. 使用命令参数对象 定义一个类,包含需要传递的多个参数,例如: ``` public class CommandParameter { public string Parameter1 { get; set; } public int Parameter2 { get; set; } } ``` 在 XAML 中,使用该类作为 InvokeCommandAction 的 CommandParameter 属性的值: ``` <i:InvokeCommandAction Command="{Binding MyCommand}" CommandParameter="{Binding CommandParameter}" /> ``` 在 ViewModel 中,命令的 Execute 方法可以接收该类的实例作为参数: ``` public RelayCommand<CommandParameter> MyCommand { get; set; } public void MyCommandExecute(CommandParameter parameter) { // 使用参数 } ``` 2. 使用触发事件的参数 在 XAML 中,可以使用 EventTrigger 触发一个事件,并且可以使用 EventTrigger 的 EventArgsConverter 属性将事件参数转换为需要的类型。例如: ``` <i:Interaction.Triggers> <i:EventTrigger EventName="MyEvent"> <i:InvokeCommandAction Command="{Binding MyCommand}"> <i:InvokeCommandAction.CommandParameter> <MultiBinding Converter="{StaticResource MyConverter}"> <Binding Path="Parameter1" /> <Binding Path="Parameter2" /> </MultiBinding> </i:InvokeCommandAction.CommandParameter> </i:InvokeCommandAction> </i:EventTrigger> </i:Interaction.Triggers> ``` 在这里,使用 MultiBinding 将多个绑定值传递给一个转换器。转换器将这些值转换为需要的类型,并且将它们封装到一个对象中,然后作为命令的参数传递给 ViewModel。 在 ViewModel 中,命令的 Execute 方法可以接收该对象作为参数: ``` public RelayCommand<MyParameter> MyCommand { get; set; } public void MyCommandExecute(MyParameter parameter) { // 使用参数 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值