编辑
2025-11-25
C#
00

目录

什么是ObservableProperty?
安装准备
详细示例集锦
示例1:基础用户信息管理
示例2:复杂设置管理器
示例3:库存管理系统
结论

什么是ObservableProperty?

ObservableProperty是CommunityToolkit.Mvvm提供的一个强大属性生成器,它能够:

  • 自动生成属性变更通知
  • 减少样板代码
  • 提供编译时代码生成
  • 支持复杂的属性变更逻辑

安装准备

Bash
# 通过NuGet安装 dotnet add package CommunityToolkit.Mvvm

详细示例集锦

示例1:基础用户信息管理

C#
// 用户信息ViewModel public partial class UserViewModel : ObservableObject { // 基础属性定义 [ObservableProperty] private string _username; [ObservableProperty] private int _age; [ObservableProperty] private string _email; // 自定义属性变更处理 partial void OnUsernameChanged(string value) { // 用户名变更时自动生成邮箱 if (!string.IsNullOrWhiteSpace(value)) { Email = $"{value.ToLower().Replace(" ", "")}@example.com"; } } // 验证方法 private bool ValidateUserInfo() { // 简单的输入验证逻辑 return !string.IsNullOrWhiteSpace(Username) && Age > 0 && !string.IsNullOrWhiteSpace(Email); } }
C#
public partial class Form1 : Form { private UserViewModel _viewModel; public Form1() { InitializeComponent(); // 初始化ViewModel _viewModel = new UserViewModel(); // 数据绑定 txtUsername.DataBindings.Add("Text", _viewModel, nameof(UserViewModel.Username), true, DataSourceUpdateMode.OnPropertyChanged); numAge.DataBindings.Add("Value", _viewModel, nameof(UserViewModel.Age), true, DataSourceUpdateMode.OnPropertyChanged); txtEmail.DataBindings.Add("Text", _viewModel, nameof(UserViewModel.Email), true, DataSourceUpdateMode.OnPropertyChanged); } private void btnShow_Click(object sender, EventArgs e) { // 序列化ViewModel对象 MessageBox.Show(JsonSerializer.Serialize(_viewModel)); } }

image.png

示例2:复杂设置管理器

C#
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace App05 { public partial class ApplicationSettingsViewModel : ObservableValidator { // 主题设置 [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(ApplyThemeCommand))] private string _currentTheme = "Light"; // 音量设置,使用验证特性 [ObservableProperty] [Range(0, 100, ErrorMessage = "音量必须在0-100之间")] private int _soundVolume = 50; // 通知设置 [ObservableProperty] private bool _enableNotifications = true; // 应用主题命令 [RelayCommand(CanExecute = nameof(CanApplyTheme))] private void ApplyTheme() { // 实际应用主题的逻辑 MessageBox.Show($"应用主题:{CurrentTheme}"); } // 命令执行条件 private bool CanApplyTheme() => !string.IsNullOrEmpty(CurrentTheme); // 音量变更处理 partial void OnSoundVolumeChanged(int value) { // 音量变更的额外逻辑 Console.WriteLine($"音量已调整为:{value}"); } } }
C#
public partial class Form2 : Form { private ApplicationSettingsViewModel _viewModel; public Form2() { InitializeComponent(); // 设置主题下拉框的数据源 cboTheme.Items.AddRange(new string[] { "Light", "Dark", "System" }); _viewModel = new ApplicationSettingsViewModel(); // 主题下拉绑定 cboTheme.DataBindings.Add("SelectedItem", _viewModel, nameof(ApplicationSettingsViewModel.CurrentTheme), true, DataSourceUpdateMode.OnPropertyChanged); // 音量滑动条绑定 trackVolume.DataBindings.Add("Value", _viewModel, nameof(ApplicationSettingsViewModel.SoundVolume), true, DataSourceUpdateMode.OnPropertyChanged); // 通知复选框绑定 chkEnableNotifications.DataBindings.Add("Checked", _viewModel, nameof(ApplicationSettingsViewModel.EnableNotifications), true, DataSourceUpdateMode.OnPropertyChanged); // 添加音量变更事件 trackVolume.ValueChanged += TrackVolume_ValueChanged; // 添加应用主题按钮点击事件 btnApplyTheme.Click += BtnApplyTheme_Click; } private void TrackVolume_ValueChanged(object sender, EventArgs e) { // 更新音量标签 lblVolumeValue.Text = $"音量: {trackVolume.Value}%"; } private void BtnApplyTheme_Click(object sender, EventArgs e) { // 调用ViewModel的应用主题命令 _viewModel.ApplyThemeCommand.Execute(null); } }

image.png

示例3:库存管理系统

C#
// 商品模型 public partial class Product : ObservableValidator { [ObservableProperty] private string _productId; [ObservableProperty] private string _name; [ObservableProperty] [Range(0, double.MaxValue)] private decimal _price; [ObservableProperty] [Range(0, int.MaxValue)] private int _stockQuantity; // 价格变更处理 partial void OnPriceChanged(decimal value) { if (value < 0) { Price = 0; } } }
C#
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace App05 { // 库存管理ViewModel public partial class InventoryViewModel : ObservableObject { // 商品列表 [ObservableProperty] private ObservableCollection<Product> _products = new(); // 当前选中商品 [ObservableProperty] private Product _selectedProduct; // 总库存价值 [ObservableProperty] private decimal _totalInventoryValue; // 添加商品命令 [RelayCommand] private void AddProduct() { var newProduct = new Product { ProductId = Guid.NewGuid().ToString(), Name = "新商品", Price = 1, StockQuantity = 2 }; Products.Add(newProduct); SelectedProduct = newProduct; RecalculateTotalValue(); } // 删除商品命令 [RelayCommand(CanExecute = nameof(CanDeleteProduct))] private void DeleteProduct() { if (SelectedProduct != null) { Products.Remove(SelectedProduct); RecalculateTotalValue(); } } // 删除命令的执行条件 private bool CanDeleteProduct() => SelectedProduct != null; // 计算总库存价值 private void RecalculateTotalValue() { TotalInventoryValue = Products.Sum(p => p.Price * p.StockQuantity); } } }
C#
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace App05 { public partial class Form3 : Form { private InventoryViewModel _viewModel; public Form3() { InitializeComponent(); // 禁用新行 dgvProducts.AllowUserToAddRows = false; // 如果没有数据则不显示空行 dgvProducts.DataSource = null; BindingSource _productBindingSource = new BindingSource(); // 创建BindingSource _productBindingSource = new BindingSource(); _viewModel = new InventoryViewModel(); // 将BindingSource绑定到ViewModel的Products集合 _productBindingSource.DataSource = _viewModel.Products; // 设置DataGridView的数据源为BindingSource dgvProducts.DataSource = _productBindingSource; // 配置DataGridView列 ConfigureDataGridViewColumns(); // 绑定总库存价值 lblTotalValue.DataBindings.Add("Text", _viewModel, nameof(InventoryViewModel.TotalInventoryValue), true, DataSourceUpdateMode.OnPropertyChanged, "总库存价值:{0:C2}"); // 订阅ViewModel的Products集合变更事件 _viewModel.Products.CollectionChanged += (s, e) => { // 刷新BindingSource _productBindingSource.ResetBindings(false); }; } private void ConfigureDataGridViewColumns() { dgvProducts.Columns.Clear(); dgvProducts.AutoGenerateColumns = false; // 商品ID列 var idColumn = new DataGridViewTextBoxColumn { DataPropertyName = "ProductId", HeaderText = "商品ID", Name = "ProductId", Width = 150 }; dgvProducts.Columns.Add(idColumn); // 商品名称列 var nameColumn = new DataGridViewTextBoxColumn { DataPropertyName = "Name", HeaderText = "商品名称", Name = "Name", Width = 150 }; dgvProducts.Columns.Add(nameColumn); // 单价列 var priceColumn = new DataGridViewTextBoxColumn { DataPropertyName = "Price", HeaderText = "单价", Name = "Price", ValueType = typeof(decimal), Width = 100 }; dgvProducts.Columns.Add(priceColumn); // 库存数量列 var quantityColumn = new DataGridViewTextBoxColumn { DataPropertyName = "StockQuantity", HeaderText = "库存数量", Name = "StockQuantity", ValueType = typeof(int), Width = 100 }; dgvProducts.Columns.Add(quantityColumn); } private void btnAdd_Click(object sender, EventArgs e) { // 执行添加商品命令 _viewModel.AddProductCommand.Execute(null); } private void dgvProducts_SelectionChanged(object sender, EventArgs e) { // 更新选中商品 if (dgvProducts.CurrentRow != null) { _viewModel.SelectedProduct = dgvProducts.CurrentRow.DataBoundItem as Product; } } private void btnDelete_Click(object sender, EventArgs e) { _viewModel.DeleteProductCommand.Execute(null); } } }

image.png

结论

ObservableProperty是现代.NET开发中简化MVVM模式的利器。通过自动生成属性变更通知,它显著减少了样板代码,提高了开发效率。

希望这篇详细的文章能帮助您深入理解和运用ObservableProperty

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!