WPF 的几种 MVVM 绑定方式

INotifyPropertyChanged 绑定

在 ViewModel 中继承 INotifyPropertyChanged

ViewModel.cs

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp
{
    public class ViewModel : INotifyPropertyChanged
    {
        public string name;
       
        public string Name
        {
            get { return name; }
            set { name = value; OnPropertyChanged("Name"); }
        }

        public ObservableCollection<Student> stuList = new ObservableCollection<Student>();

        public ObservableCollection<Student> StuList
        {
            get { return stuList; }
            set { stuList = value; OnPropertyChanged("StuList"); }
        }

		public event PropertyChangedEventHandler? PropertyChanged;
        
        protected void OnPropertyChanged(string properName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(properName));
        }
        
        public ViewModel()
        {
            Name = "hello";
            Task.Run(async () =>
            {
                await Task.Delay(3000);
                Name = "no";
                stuList.Add(new Student() { Address = "12223", ClassName = "12223", UserName = "2" });

            });
        }
    }
}

XAML

xaml 复制代码
<Grid Grid.Row="0">
    <StackPanel>
        <TextBox  Text="{Binding Name}" />
        <TextBox  Text="{Binding Name}" />
        <TextBox  Text="{Binding Name}" />
        <Button Command="{Binding SavaCommand}" Height="30" />
    </StackPanel>
</Grid>
<Grid Grid.Row="1">
    <ListView x:Name="lv" ItemsSource="{Binding StuList, Mode=TwoWay}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding UserName}" />
                <GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding ClassName}" />
                <GridViewColumn Header="Mail" Width="150" DisplayMemberBinding="{Binding Address}" />
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

MvvmLight 绑定(已经很久没有更新了)

在 ViewModel 中继承 ViewModelBase

引用程序集 using GalaSoft.MvvmLight;

csharp 复制代码
using GalaSoft.MvvmLight;
using System;
using System.Collections.Generic;
using System.Text;

namespace WpfStudy.ViewModel
{
    public class CanvasViewModel: ViewModelBase
    {
        public string name;

        public string Name
        {
            get { return name; }
            set { name = value; base.RaisePropertyChanged(() => Name); }
        }
    }
}

事件绑定

可传参数

引入程序集

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

xaml 复制代码
 <Canvas x:Name="Canvas" Grid.Row="1" Background="Black">
     <i:Interaction.Triggers>
         <i:EventTrigger EventName="PreviewMouseWheel">
             <i:InvokeCommandAction Command="{Binding PreviewMouseWheelCommand}" CommandParameter="1"  />
         </i:EventTrigger>
     </i:Interaction.Triggers>
</Canvas>

InvokeCommandAction CommandParameter 属性可传传参

可传事件

引入程序集

http://schemas.microsoft.com/expression/2010/interactions

xaml 复制代码
<Canvas x:Name="Canvas" Grid.Row="1" Background="Black">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="PreviewMouseWheel">
            <m:EventToCommand Command="{Binding PreviewMouseWheelCommand}" PassEventArgsToCommand="True"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Canvas>

EventToCommand PassEventArgsToCommand 属性为True可传事件对象

可传参数和事件

引入程序集

xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

可用此命名空间替换 http://schemas.microsoft.com/expression/2010/interactivityhttp://schemas.microsoft.com/expression/2010/interactions 两个命名空间

xaml 复制代码
<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
        <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" PassEventArgsToCommand="True"/>
    </i:EventTrigger>
    <i:EventTrigger EventName="PreviewTextInput">
        <i:InvokeCommandAction Command="{Binding PreviewTextInputCommand}" CommandParameter="1"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

可以同时使用 PassEventArgsToCommandCommandParameter 两个属性

ViewModel 层

csharp 复制代码
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;

namespace WpfStudy.ViewModel
{
    public class CanvasViewModel: ViewModelBase
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; base.RaisePropertyChanged(() => Name); }
        }

        public RelayCommand<object> PreviewMouseWheelCommand { get; set; };


        public CanvasViewModel()
        {
            PreviewMouseWheelCommand = new RelayCommand<object>(PreviewMouseWheel);
        }


        private void PreviewMouseWheel(object e)
        {

        }
    } 
}

RelayCommand

引用程序集 using GalaSoft.MvvmLight.Command;

Tips:双向绑定的数据变更还是需要使用公用变量来变更绑定的值。

CommunityToolkit.Mvvm 绑定

微软推出的快速且模块化的 MVVM 库

在 ViewModel 中继承 ObservableObject

引用程序集 using CommunityToolkit.Mvvm.ComponentModel;

csharp 复制代码
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace PrecisionToolset.ViewModels
{
    public class TestViewModel : ObservableObject
    {
        private string _status = string.Empty;
        public string Status
        {
            get => _status;
            set => SetProperty(ref _status, value);
        }

        public ICommand buttonCommand { get; }

        public TestViewModel() 
        { 
            Status = "Hello";
            buttonCommand = new RelayCommand<object>(ButtonClick);
        }

        private void ButtonClick(object b)
        {
            int a = 1;
        }
    }
}

事件绑定

使用 CommunityToolkit.Mvvm 的事件绑定方法和MvvmLight基本上一致。

XAML中可以引入 xmlns:i="http://schemas.microsoft.com/xaml/behaviors" 来实现可传入参数和事件。

XAML 中绑定的用法

CommandParameter 参数绑定

  • 传入当前组件的某一个属性:CommandParameter="{Binding Header, RelativeSource={RelativeSource Self}}"
  • 传入某一个其他组件对象:CommandParameter="{Binding ElementName=menuBtn}" (menuBtn 是一个按钮的x:name)
相关推荐
江山如画,佳人北望1 小时前
C#程序入门
开发语言·windows·c#
与火星的孩子对话2 小时前
Unity进阶课程【六】Android、ios、Pad 终端设备打包局域网IP调试、USB调试、性能检测、控制台打印日志等、C#
android·unity·ios·c#·ip
future14122 小时前
C#每日学习日记
java·学习·c#
军训猫猫头5 小时前
1.如何对多个控件进行高效的绑定 C#例子 WPF例子
开发语言·算法·c#·.net
葬歌倾城21 小时前
JSON的缩进格式方式和紧凑格式方式
c#·json
Eiceblue1 天前
使用 C# 发送电子邮件(支持普通文本、HTML 和附件)
开发语言·c#·html·visual studio
小小小小王王王1 天前
hello判断
开发语言·c#
金增辉1 天前
基于C#的OPCServer应用开发,引用WtOPCSvr.dll
c#
future14121 天前
C#学习日记
开发语言·学习·c#
傻啦嘿哟1 天前
Python 办公实战:用 python-docx 自动生成 Word 文档
开发语言·c#