编辑
2025-11-25
C#
0

目录

概述
环境准备
项目结构
详细代码实现
Model 层
Service 层
ViewModel 层
View 层
程序入口配置依赖注入
注意事项
优势
总结

概述

本文将详细介绍如何在 WinForm 应用程序中使用 CommunityToolkit.Mvvm 结合依赖注入实现 MVVM 模式。我们将通过一个具体的示例来展示整个实现过程。

环境准备

首先需要安装以下 NuGet 包:

XML
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />

image.png

项目结构

C#
├── Models │ └── UserModel.cs ├── ViewModels │ └── MainViewModel.cs ├── Views │ └── MainForm.cs ├── Services │ └── IUserService.cs │ └── UserService.cs └── Program.cs

详细代码实现

Model 层

C#
// Models/UserModel.cs public class UserModel { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }

Service 层

C#
// Services/IUserService.cs public interface IUserService { Task<List<UserModel>> GetUsersAsync(); Task<bool> AddUserAsync(UserModel user); } // Services/UserService.cs public class UserService : IUserService { // 模拟数据库 private readonly List<UserModel> _users = new(); public async Task<List<UserModel>> GetUsersAsync() { // 模拟异步操作 await Task.Delay(100); return _users; } public async Task<bool> AddUserAsync(UserModel user) { await Task.Delay(100); _users.Add(user); return true; } }

ViewModel 层

C#
// ViewModels/MainViewModel.cs public partial class MainViewModel : ObservableObject { private readonly IUserService _userService; [ObservableProperty] private ObservableCollection<UserModel> users = new(); [ObservableProperty] private string userName; [ObservableProperty] private int userAge; public MainViewModel(IUserService userService) { _userService = userService; // 构造函数中加载数据 LoadUsersAsync().ConfigureAwait(false); } // 加载用户列表 private async Task LoadUsersAsync() { var userList = await _userService.GetUsersAsync(); Users = new ObservableCollection<UserModel>(userList); } // 添加用户命令 [RelayCommand] private async Task AddUserAsync() { if (string.IsNullOrEmpty(UserName)) return; var user = new UserModel { Name = UserName, Age = UserAge }; var result = await _userService.AddUserAsync(user); if (result) { Users.Add(user); // 清空输入 UserName = string.Empty; UserAge = 0; } } }

View 层

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; using System.Xml.Linq; using App12.ViewModels; using static System.Net.Mime.MediaTypeNames; namespace App12.Views { public partial class MainForm : Form { private readonly MainViewModel _viewModel; private BindingSource bindingSource; // 声明为类成员 public MainForm(MainViewModel viewModel) { InitializeComponent(); _viewModel = viewModel; // 设置数据绑定 SetupDataBindings(); // 设置命令绑定 SetupCommandBindings(); } private void SetupDataBindings() { // 用户列表绑定 bindingSource = new BindingSource(); bindingSource.DataSource = _viewModel.Users; dataGridView1.DataSource = bindingSource; // 文本框绑定 txtName.DataBindings.Add(new Binding("Text", _viewModel, nameof(_viewModel.UserName), true, DataSourceUpdateMode.OnPropertyChanged)); numAge.DataBindings.Add(new Binding("Value", _viewModel, nameof(_viewModel.UserAge), true, DataSourceUpdateMode.OnPropertyChanged)); } private void SetupCommandBindings() { // 添加用户按钮点击事件 btnAdd.Click += async (s, e) => { await _viewModel.AddUserCommand.ExecuteAsync(null); var result = _viewModel.Users; bindingSource.ResetBindings(false); }; } } }

这里没找到好的方法像WPF一样ObservableCollection 通知datagrid 。

程序入口配置依赖注入

C#
using App12.Services; using App12.ViewModels; using App12.Views; using Microsoft.Extensions.DependencyInjection; namespace App12 { internal static class Program { public static IServiceProvider ServiceProvider { get; private set; } /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); // 配置依赖注入 var services = new ServiceCollection(); ConfigureServices(services); ServiceProvider = services.BuildServiceProvider(); // 从服务容器中获取主窗体并运行 var mainForm = ServiceProvider.GetRequiredService<MainForm>(); Application.Run(mainForm); } private static void ConfigureServices(IServiceCollection services) { // 注册服务 services.AddSingleton<IUserService, UserService>(); // 注册 ViewModel services.AddTransient<MainViewModel>(); // 注册主窗体 services.AddTransient<MainForm>(); } } }

image.png

注意事项

  1. WinForms 的数据绑定相对 WPF 较为简单,需要手动设置
  2. 确保在 UI 线程上更新界面元素
  3. 使用 async/await 处理异步操作
  4. 注意服务的生命周期管理(Singleton/Transient)

优势

  1. 代码结构清晰,职责分明
  2. 便于单元测试
  3. 使用依赖注入提高代码的可维护性和可测试性
  4. 使用 CommunityToolkit.Mvvm 简化了 MVVM 模式的实现

总结

这个示例展示了如何在 WinForm 应用程序中使用 CommunityToolkit.Mvvm 和依赖注入。通过遵循 MVVM 模式,可以使代码更加清晰、可维护,同时也便于进行单元测试。虽然 WinForm 不像 WPF 那样天生支持 MVVM 模式,但通过适当的设计和工具的使用,同样可以实现清晰的分层架构。

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:技术老小子

本文链接:

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