INotifyPropertyChanged 绑定
在 ViewModel 中继承 INotifyPropertyChanged
ViewModel.cs
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
<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;
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"
<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
<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/interactivity
和 http://schemas.microsoft.com/expression/2010/interactions
两个命名空间
<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>
可以同时使用 PassEventArgsToCommand
和 CommandParameter
两个属性
ViewModel 层
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;
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)