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)
相关推荐
虚假程序设计2 小时前
pythonnet python图像 C# .NET图像 互转
开发语言·人工智能·python·opencv·c#·.net
我是苏苏3 小时前
Web开发:ABP框架3——入门级别的接口增删改查实现原理
c#·web开发·abp
Zhen (Evan) Wang4 小时前
.NET 6 API + Dapper + SQL Server 2014
数据库·c#·.net
VB.Net4 小时前
EmguCV学习笔记 VB.Net 12.3 OCR
opencv·计算机视觉·c#·ocr·图像·vb.net·emgucv
俊哥V4 小时前
[备忘]测算.net中对象所占用的内存
c#·.net·内存
闻缺陷则喜何志丹4 小时前
HObject复制耗时试用
c#·指针·halcon·key·图形图形·用时·非安全代码
friklogff4 小时前
【C#生态园】从数据分析到机器学习:掌握C#统计学库的核心功能
机器学习·数据分析·c#
我命由我123454 小时前
GPIO 理解(基本功能、模拟案例)
linux·运维·服务器·c语言·c++·嵌入式硬件·c#
VB.Net5 小时前
EmguCV学习笔记 C# 12.3 OCR
opencv·计算机视觉·c#·ocr·vb.net·emgucv
吃饭只吃七分饱10 小时前
arm开发板通信
arm开发·c#