在 MVVM 架构中,属性变更通知是保持视图和模型同步的关键机制。NotifyPropertyChangedFor 特性是 CommunityToolkit.Mvvm 提供的一个强大工具,它允许我们在一个属性发生变更时,自动触发其他相关属性的通知。

NotifyPropertyChangedFor 特性的主要作用是:
PropertyChanged 事件C#using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace App6
{
public partial class UserProfileViewModel : ObservableObject
{
// 使用 [ObservableProperty] 和 [NotifyPropertyChangedFor] 特性
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(FullName))]
[NotifyPropertyChangedFor(nameof(IsNameValid))]
private string _firstName;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(FullName))]
[NotifyPropertyChangedFor(nameof(IsNameValid))]
private string _lastName;
[ObservableProperty]
private DateTime _birthDate;
// 依赖属性:当 FirstName 或 LastName 变更时,FullName 也会触发通知
public string FullName => $"{_firstName} {_lastName}".Trim();
// 验证姓名是否有效的计算属性
public bool IsNameValid =>
!string.IsNullOrWhiteSpace(_firstName) &&
!string.IsNullOrWhiteSpace(_lastName);
// 计算年龄的属性
public int Age
{
get
{
var today = DateTime.Today;
var age = today.Year - _birthDate.Year;
if (_birthDate.Date > today.AddYears(-age)) age--;
return age;
}
}
// 构造函数
public UserProfileViewModel()
{
_firstName = string.Empty;
_lastName = string.Empty;
_birthDate = DateTime.Today.AddYears(-25); // 默认设置为25岁
}
// 重置方法
[RelayCommand]
private void ResetProfile()
{
FirstName = string.Empty;
LastName = string.Empty;
BirthDate = DateTime.Today.AddYears(-25);
}
// 保存配置文件的命令
[RelayCommand(CanExecute = nameof(IsNameValid))]
private void SaveProfile()
{
// 实际保存逻辑(这里只是示例)
Console.WriteLine($"保存用户配置:{FullName}, 年龄:{Age}");
}
// 验证方法
public bool ValidateProfile()
{
return IsNameValid && Age >= 18;
}
// 格式化显示方法
public string GetFormattedProfile()
{
return $"姓名:{FullName}\n" +
$"年龄:{Age}\n" +
$"出生日期:{BirthDate:yyyy-MM-dd}";
}
}
}
C#internal class Program
{
static void Main(string[] args)
{
var viewModel = new UserProfileViewModel();
// 演示属性变更
viewModel.FirstName = "张";
viewModel.LastName = "三";
viewModel.BirthDate = DateTime.Today.AddYears(-30);
// 使用命令
viewModel.SaveProfileCommand.Execute(null);
// 输出格式化信息
Console.WriteLine(viewModel.GetFormattedProfile());
// 重置配置
viewModel.ResetProfileCommand.Execute(null);
}
}
C#// 产品管理器,演示集合操作
public class ProductManager
{
// 产品集合
public ObservableCollection<ProductViewModel> Products { get; } = new();
// 添加产品
public void AddProduct(ProductViewModel product)
{
if (product.ValidateProduct())
{
Products.Add(product);
}
}
// 计算总库存价值
public decimal CalculateTotalInventoryValue()
{
decimal total = 0;
foreach (var product in Products)
{
total += product.TotalPrice;
}
return total;
}
}
C#static void Main(string[] args)
{
// 创建产品
var laptop = new ProductViewModel
{
ProductName = "高性能笔记本",
Price = 1200,
Quantity = 5,
Weight = 2.5
};
// 应用折扣
laptop.ApplyDiscountCommand.Execute(0.1m); // 10%折扣
// 输出产品详情
Console.WriteLine(laptop.GetProductDetails());
// 产品管理
var manager = new ProductManager();
manager.AddProduct(laptop);
// 计算总库存价值
Console.WriteLine($"总库存价值:{manager.CalculateTotalInventoryValue():C}");
}

C#public partial class ProductViewModel : ObservableObject
{
// 价格属性,影响总价和高级产品状态
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(TotalPrice))]
[NotifyPropertyChangedFor(nameof(IsPremiumProduct))]
[NotifyPropertyChangedFor(nameof(DiscountAmount))]
private decimal _price;
// 数量属性,影响总价
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(TotalPrice))]
[NotifyPropertyChangedFor(nameof(TotalWeight))]
private int _quantity;
// 重量属性
[ObservableProperty]
private double _weight;
// 产品名称
[ObservableProperty]
private string _productName;
// 折扣率
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(DiscountAmount))]
private decimal _discountRate;
// 总价格:当价格或数量变更时,自动通知
public decimal TotalPrice => _price * _quantity;
// 总重量:当数量变更时,自动通知
public double TotalWeight => _weight * _quantity;
// 高级产品判断:当价格变更时,自动通知
public bool IsPremiumProduct => _price > 1000;
// 折扣金额:当价格或折扣率变更时,自动通知
public decimal DiscountAmount => _price * _discountRate;
// 最终价格:考虑折扣
public decimal FinalPrice => TotalPrice - DiscountAmount;
// 库存状态
public bool IsInStock => _quantity > 0;
// 构造函数
public ProductViewModel()
{
_price = 0;
_quantity = 0;
_weight = 0;
_productName = string.Empty;
_discountRate = 0;
}
// 添加库存命令
[RelayCommand]
private void AddStock(int additionalQuantity)
{
if (additionalQuantity > 0)
{
Quantity += additionalQuantity;
}
}
// 移除库存命令
[RelayCommand(CanExecute = nameof(IsInStock))]
private void RemoveStock(int removeQuantity)
{
if (removeQuantity > 0 && removeQuantity <= _quantity)
{
Quantity -= removeQuantity;
}
}
// 应用折扣命令
[RelayCommand]
private void ApplyDiscount(decimal discountPercentage)
{
if (discountPercentage >= 0 && discountPercentage <= 1)
{
DiscountRate = discountPercentage;
}
}
// 产品验证方法
public bool ValidateProduct()
{
return !string.IsNullOrWhiteSpace(_productName)
&& _price > 0
&& _quantity >= 0;
}
// 获取产品详情
public string GetProductDetails()
{
return $"产品:{_productName}\n" +
$"单价:{_price:C}\n" +
$"数量:{_quantity}\n" +
$"总价:{TotalPrice:C}\n" +
$"折扣:{DiscountAmount:C}\n" +
$"最终价格:{FinalPrice:C}\n" +
$"是否为高级产品:{IsPremiumProduct}";
}
}

[ObservableProperty] 结合 [NotifyPropertyChangedFor]NotifyPropertyChangedFor 仅在使用源生成器时有效partial 类和 ObservableObject 基类NotifyPropertyChangedFor 特性是 CommunityToolkit.Mvvm 中简化属性变更通知的强大工具。通过智能地使用这一特性,可以编写更简洁、更易维护的 MVVM 代码。
希望这篇文章对你理解和使用 NotifyPropertyChangedFor 有所帮助!
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!