C#中SetProperty方法使用

发布于:2025-05-13 ⋅ 阅读:(16) ⋅ 点赞:(0)

SetProperty 是 MVVM(Model-View-ViewModel) 模式中用于实现 属性变更通知(INotifyPropertyChanged) 的核心方法,主要用于在属性值变化时自动更新 UI 绑定。


1. SetProperty 的基本作用

  • 更新字段值:修改属性的私有字段(backing field)。

  • 触发通知:如果值发生变化,自动发出 PropertyChanged 事件,通知 UI 更新。

  • 避免重复更新:如果新值和旧值相同,则不触发事件,提高性能。


2. SetProperty 的典型实现

通常在 ViewModel 基类 中定义,例如:

(1)基础版本(带 [CallerMemberName] 自动获取属性名)

using System.ComponentModel;
using System.Runtime.CompilerServices;

public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;

    protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = "")
    {
        if (EqualityComparer<T>.Default.Equals(field, value))
            return false; // 值未变化,不触发更新

        field = value; // 更新字段值
        OnPropertyChanged(propertyName); // 触发通知
        return true;
    }

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
参数说明
  • ref T field:属性的私有字段(如 axisXStatusInfo)。

  • T value:要设置的新值。

  • [CallerMemberName] string propertyName:自动获取调用该方法的属性名(如 "AxisXStatusInfo")。

返回值
  • true:值已更改,并触发了 PropertyChanged 事件。

  • false:值未更改,不触发事件。


(2)扩展版本(支持自定义回调)

protected bool SetProperty<T>(
    ref T field,
    T value,
    Action<T>? onChanged = null,
    [CallerMemberName] string propertyName = "")
{
    if (EqualityComparer<T>.Default.Equals(field, value))
        return false;

    field = value;
    onChanged?.Invoke(value); // 可选:值变化后执行额外逻辑
    OnPropertyChanged(propertyName);
    return true;
}
用法示例
private string _name;

public string Name
{
    get => _name;
    set => SetProperty(ref _name, value, (newValue) => 
    {
        Console.WriteLine($"Name 从 {_name} 变为 {newValue}");
    });
}

3. 如何在 ViewModel 中使用 SetProperty

假设有一个 ViewModel 继承自 ObservableObject

public class MainViewModel : ObservableObject
{
    private string _status;

    public string Status
    {
        get => _status;
        set => SetProperty(ref _status, value); // 自动触发 UI 更新
    }

    private int _count;

    public int Count
    {
        get => _count;
        set => SetProperty(ref _count, value, onChanged: (newCount) =>
        {
            Console.WriteLine($"Count 更新为 {newCount}");
        });
    }
}

4. 为什么需要 SetProperty

  • 简化 INotifyPropertyChanged 的实现:避免在每个属性的 set 里手动写 OnPropertyChanged

  • 提高性能:仅在值真正变化时触发事件。

  • 支持自动属性名推断[CallerMemberName] 避免硬编码属性名,减少错误。


5. 常见问题

(1)SetProperty 和 OnPropertyChanged 的区别?

  • SetProperty:用于 修改属性值并触发通知

  • OnPropertyChanged:仅 手动触发通知(适用于计算属性或依赖属性)。

(2)如果不使用 SetProperty,传统写法是怎样的?

private string _name;

public string Name
{
    get => _name;
    set
    {
        if (_name != value)
        {
            _name = value;
            OnPropertyChanged(nameof(Name));
        }
    }
}

SetProperty 让这段代码更简洁、更安全。


总结

功能 SetProperty 的作用
更新字段值 field = value
自动触发 UI 更新 调用 OnPropertyChanged
避免重复更新 检查新旧值是否相同
支持回调 可选 onChanged 逻辑
自动获取属性名 [CallerMemberName]

如果你的项目使用 WPF / MAUI / Xamarin / Avalonia 等 MVVM 框架,SetProperty 是管理属性变更的最佳实践!


网站公告

今日签到

点亮在社区的每一天
去签到