WPF中MVVM手动实现PropertyChanged和RelayCommand

50 篇文章 0 订阅

背景:PropertyChanged和Command总是没有记住怎么写

PropertyChanged:

public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

-- 使用上特性[CallerMemberName]的作用就是由原本调用这个方法的使用要传入属性的名称作为这个方法的参数,但是现在就不用了,直接调用方法,会自动将参数(这里是属性的名称)传过去。所以调用就直接OnPropertyChanged()就行了,不需要原理的nameof(属性名)

补充:也可以加多一层使用表达式树做形参

public void RaisePropertyChanged<T>(Expression<Func<T>> expression)
{
    MemberExpression member = (MemberExpression)expression.Body;
    string propName = member.Member.Name;
    RaisePropertyChanged(propName);
}

RelayCommand:

public class RelayCommand : ICommand
{
    // 不需要怎么访问,就私有起来就行
    private readonly Action<object> _execute;
    private readonly Predicate<object> _canExecute; // 这个就是Func<object, bool>

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        _execute = execute ?? throw new ArgumentNullException(nameof(execute));   // 一定要有这个值
        _canExecute = canExecute;
    }

    // 自动调用CanExecute
    public event EventHandler? CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove {  CommandManager.RequerySuggested -= value; }
    }

    // 手动调用CanExecute
    public void RaiseCanExecuteChanged()
    {
        CommandManager.InvalidateRequerySuggested();
    }

    public bool CanExecute(object? parameter)
    {
        //Console.WriteLine(".....");
        return _canExecute?.Invoke(parameter) ?? true;  // 有就调用,没有就返回true
    }

    public void Execute(object? parameter)
    {
        //Console.WriteLine("激活方法");
        //Debug.WriteLine("激活方法`11");
        _execute?.Invoke(parameter);    // 调用订阅的方法
    }
}

泛型版本:

public class RelayCommand<T> : ICommand
{
    private readonly Action<T> _execute;
    private readonly Func<T, bool> _canExecute;

    // 构造方法订阅
    public RelayCommand(Action<T> execute, Func<T, bool> canExecute)
    {
        _execute = execute ??throw new ArgumentNullException(nameof(execute));
        _canExecute = canExecute;
    }

    // 自动canExecute
    public event EventHandler? CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    // 手动调用onExecute
    public void RaiseCanExecuteChanged()
    {
        CommandManager.InvalidateRequerySuggested();
    }

    public bool CanExecute(object? parameter)
    {
        return _canExecute?.Invoke((T)parameter) ?? true;
    }

    public void Execute(object? parameter)
    {
        _execute?.Invoke((T)parameter);
    }
}

手写好麻烦还是用MvvmToolkit吧:MvvmToolkit的使用_mvvmtoolkit cs0117-CSDN博客

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里我可以给你一个WPF使用MvvmLight实现MVVM的工程实例。 首先,你需要在Visual Studio安装MvvmLight框架。可以通过NuGet来安装MvvmLight库,具体步骤如下: 1. 在Visual Studio打开你的WPF工程。 2. 在Solution Explorer窗口右键单击工程,选择“Manage NuGet Packages”。 3. 在“NuGet Package Manager”窗口,在搜索框输入“MvvmLight”,选择“MvvmLight”并安装。 接下来,我们就可以开始实现MVVM模式了。 1. 创建一个新的ViewModel类,继承自ViewModelBase类。 ```csharp using GalaSoft.MvvmLight; public class MainViewModel : ViewModelBase { //ViewModel的属性和命令 } ``` 2. 在ViewModel实现需要绑定的属性和命令。 ```csharp private string _message; public string Message { get { return _message; } set { if (_message != value) { _message = value; RaisePropertyChanged(() => Message); } } } private RelayCommand _showMessageCommand; public RelayCommand ShowMessageCommand { get { if (_showMessageCommand == null) { _showMessageCommand = new RelayCommand(() => { MessageBox.Show(Message); }); } return _showMessageCommand; } } ``` 3. 在View绑定ViewModel的属性和命令。 ```xaml <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" xmlns:vm="clr-namespace:WpfApp1.ViewModel" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.DataContext> <vm:MainViewModel /> </Window.DataContext> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <TextBox Text="{Binding Message, UpdateSourceTrigger=PropertyChanged}" /> <Button Grid.Row="1" Content="Show Message" Command="{Binding ShowMessageCommand}" /> </Grid> </Window> ``` 在这个例子,我们创建了一个MainViewModel类,其包含了一个Message属性和一个ShowMessageCommand命令。在View,我们使用DataContext将ViewModel实例与View绑定,并使用Binding将ViewModel的属性和命令绑定到View上。 这样,我们就成功地使用MvvmLight实现MVVM模式。当用户在TextBox输入文字并点击Button时,将会弹出一个对话框显示用户输入的文字。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值