【C#】在 WinForms 中使用 MVVM(Model-View-ViewModel) 设计模式

news/2024/10/22 21:40:31/

在这里插入图片描述

结合当前的 DevExpress 项目,在 WinForms 中使用 MVVM(Model-View-ViewModel) 设计模式。这个例子将通过数据绑定、命令绑定来展示 MVVM 模式的运用。

1. 项目结构

假设我们要实现一个简单的应用程序,它有一个文本框和一个按钮,用户输入内容后点击按钮,内容会显示在列表框中。这种交互将通过 MVVM 设计模式来完成,且我们会使用 DevExpress 的控件。

项目结构如下:

DXApplication1
├── Model
│   └── DataModel.cs        // 模型,表示数据
├── View
│   ├── MainView.cs         // 视图,WinForms 窗体
│   ├── MainView.Designer.cs // 设计器自动生成的代码
│   └── MainView.resx       // 窗体资源文件
└── ViewModel└── MainViewModel.cs    // 视图模型,处理逻辑和数据绑定

2. Model (数据模型)

首先,我们创建一个数据模型来存储用户输入的数据。

// Model/DataModel.cs
namespace DXApplication1.Model
{public class DataModel{public string UserInput { get; set; }public DataModel(string userInput){UserInput = userInput;}}
}

这个 DataModel 类是一个简单的数据结构,用来存储用户输入的字符串。

3. View (视图)

MainView.cs 中,我们设计一个界面,有一个文本框、一个按钮和一个列表框。我们使用 DevExpress 提供的控件来展示这些元素。

// View/MainView.cs
using System;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DXApplication1.ViewModel;namespace DXApplication1.View
{public partial class MainView : DevExpress.XtraEditors.XtraForm{private MainViewModel viewModel;public MainView(){InitializeComponent();// 初始化 ViewModelviewModel = new MainViewModel();this.DataBindings.Add(new Binding("Text", viewModel, "WindowTitle")); // 绑定窗体标题this.textEditUserInput.DataBindings.Add(new Binding("Text", viewModel, "UserInput", true, DataSourceUpdateMode.OnPropertyChanged));this.simpleButtonSubmit.DataBindings.Add(new Binding("Enabled", viewModel, "IsSubmitEnabled"));this.listBoxControlOutput.DataSource = viewModel.Items;// 将按钮点击事件绑定到 ViewModel 的命令this.simpleButtonSubmit.Click += (s, e) => viewModel.SubmitCommand.Execute(null);}}
}
关键点:
  • 数据绑定:文本框绑定到 UserInput 属性,列表框绑定到 Items 集合。
  • 按钮点击事件:按钮点击事件绑定到 ViewModel 的 SubmitCommand 命令。

我们假设 InitializeComponent() 方法自动生成了如下控件:

  • textEditUserInput:文本框,用于输入用户内容。
  • simpleButtonSubmit:按钮,用于提交输入。
  • listBoxControlOutput:列表框,用于显示提交后的内容。

4. ViewModel (视图模型)

在 ViewModel 中,我们管理用户的输入和提交逻辑。这个 ViewModel 负责处理所有与视图的交互,并使用 INotifyPropertyChanged 来实现数据绑定。

// ViewModel/MainViewModel.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using DevExpress.Mvvm;
using DXApplication1.Model;namespace DXApplication1.ViewModel
{public class MainViewModel : ViewModelBase{private string userInput;private bool isSubmitEnabled;public MainViewModel(){Items = new ObservableCollection<DataModel>();SubmitCommand = new DelegateCommand(OnSubmit, CanSubmit);}// 绑定到输入框的属性public string UserInput{get => userInput;set{if (SetProperty(ref userInput, value, nameof(UserInput))){// 每次修改输入时,检查是否可以提交isSubmitEnabled = !string.IsNullOrWhiteSpace(userInput);RaisePropertyChanged(nameof(IsSubmitEnabled));}}}// 提交按钮是否可用public bool IsSubmitEnabled => isSubmitEnabled;// 提交命令public ICommand SubmitCommand { get; }// 存储用户提交的列表public ObservableCollection<DataModel> Items { get; }// 提交按钮的逻辑private void OnSubmit(){// 将输入添加到列表中Items.Add(new DataModel(UserInput));UserInput = string.Empty;  // 清空输入框}// 提交按钮是否可用的逻辑private bool CanSubmit(){return !string.IsNullOrWhiteSpace(UserInput);}}
}
关键点:
  • UserInput:与视图中的输入框绑定,用户在输入框中的内容通过 UserInput 属性与视图模型中的数据同步。
  • Items:与列表框绑定,存储用户提交的所有输入内容。
  • SubmitCommand:与按钮绑定,处理提交逻辑。我们使用了 DevExpress 提供的 DelegateCommand 来处理按钮的点击事件。
  • INotifyPropertyChanged:通过继承 ViewModelBase,视图模型自动支持属性变更通知,使得视图可以根据属性变化更新。

5. 运行效果

当运行项目时:

  1. 用户在文本框中输入文字。
  2. 只有在文本框不为空时,提交按钮才会被启用(通过 IsSubmitEnabled 控制)。
  3. 用户点击提交按钮后,输入的文字会被添加到列表框中,显示在界面上,输入框会被清空,等待新的输入。

6. 总结

  • ModelDataModel 代表数据(用户输入内容),用于存储信息。
  • ViewMainView 是用户界面,负责展示控件。通过数据绑定与 ViewModel 交互。
  • ViewModelMainViewModel 负责处理用户输入和数据逻辑,它通过 UserInput 属性和 SubmitCommand 命令与视图交互。INotifyPropertyChanged 使得视图在 ViewModel 属性变化时自动更新。

这是一个基础的 MVVM 实例,它展示了如何在 WinForms 项目中使用 DevExpress 组件和 MVVM 模式来实现清晰的逻辑分离。通过 MVVM,界面(View)和逻辑(ViewModel)完全分离,代码更加模块化、易于测试和维护


http://www.ppmy.cn/news/1541161.html

相关文章

15分钟学Go 第7天:控制结构 - 条件语句

第7天&#xff1a;控制结构 - 条件语句 在Go语言中&#xff0c;控制结构是程序逻辑的重要组成部分。通过条件语句&#xff0c;我们可以根据不同的条件采取不同的行动。今天我们将详细探讨Go语言中的两种主要条件结构&#xff1a;if语句和switch语句。理解这些控制结构对于编写…

Vue 3中集成Element Plus组件库

文章目录 一、Element Plus简介二、安装Element Plus2.1 安装Element Plus2.2 引入Element Plus三、使用Element Plus组件3.1 创建组件3.2 组件引入四、总结随着前端开发的快速发展,组件库已经成为开发实践中不可或缺的部分。 Vue 3作为一个现代的 JavaScript框架,其灵活性…

双11直播激发消费潜力,抖音电商作者带货成交额同比增长超70%

“双11”大促如火如荼&#xff0c;来自各行各业的抖音电商作者精心选品&#xff0c;为广大消费者带来丰富的优价好物。抖音电商数据显示&#xff0c;10月18日至20日&#xff0c;平台上作者累计带货成交额同比去年提升超70%&#xff0c;超10万名作者带货成交额同比增长300%&…

关于上传 GP aab 包,报错 “Invalid uncompressed glob“ 的解决

之前打包盒上传 aab 包一直没问题&#xff0c;今天突然报错如下&#xff1a; 针对您上传的 App Bundle 运行 bundletool build-apks 时出错。 请在本地运行 bundletool build-apks&#xff0c;确保您的 App Bundle 有效&#xff0c;然后重试。 错误&#xff1a;Invalid uncomp…

数据脱敏方案总结

什么是数据脱敏 数据脱敏的定义 数据脱敏百度百科中是这样定义的&#xff1a; 数据脱敏&#xff0c;指对某些敏感信息通过脱敏规则进行数据的变形&#xff0c;实现敏感隐私数据的可靠保护。这样就可以在开发、测试和其它非生产环境以及外包环境中安全地使用脱敏后的真实数据集…

[图形学]蒙特卡洛积分方法介绍及其方差计算

一、简介 本文介绍了蒙特卡洛积分算法的基本原理和其误差计算。 二、蒙特卡洛积分介绍 1. 介绍 蒙特卡洛积分算法是一种数值积分算法&#xff0c;用于对复杂函数进行积分。 例如&#xff0c;对于目标积分函数&#xff1a; ∫ a b f ( x ) d x (1) \int_{a}^{b}f(x)\rm{d}x…

MongoDB文档的详细使用说明

以下是关于MongoDB文档的详细使用说明&#xff1a; 1. 文档的概念 文档是MongoDB中数据的基本单元&#xff0c;它是一个类似于JSON格式的键值对数据结构&#xff0c;也被称为BSON&#xff08;Binary JSON&#xff09;格式。文档可以包含不同类型的数据字段&#xff0c;并且可…

Android 10.0 Camera2 拍照镜像功能实现

1.前言 在10.0的系统rom定制化开发中,在进行camera2的相关拍照功能开发中,在某些时候会遇到拍照照片 左右镜像的问题,就是照片左半边和右半边是反的,所以就需要在拍照的时候保存图片的时候实现 左右镜像功能,接下来就来分析下拍照保存图片的流程 2.Camera2 拍照镜像功能实…