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

news2024/10/23 2:32:55

在这里插入图片描述

结合当前的 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();

            // 初始化 ViewModel
         viewModel = 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.coloradmin.cn/o/2221242.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++指南】类和对象(四):类的默认成员函数——全面剖析 : 拷贝构造函数

引言 拷贝构造函数是C中一个重要的特性&#xff0c;它允许一个对象通过另一个已创建好的同类型对象来初始化。 了解拷贝构造函数的概念、作用、特点、规则、默认行为以及如何自定义实现&#xff0c;对于编写健壮和高效的C程序至关重要。 C类和对象系列文章&#xff0c;可点击下…

【计网】理解TCP全连接队列与tcpdump抓包

希望是火&#xff0c;失望是烟&#xff0c; 生活就是一边点火&#xff0c;一边冒烟。 理解TCP全连接队列与tcpdump抓包 1 TCP 全连接队列1.1 重谈listen函数1.2 初步理解全连接队列1.3 深入理解全连接队列 2 tcpdump抓包 1 TCP 全连接队列 1.1 重谈listen函数 这里我们使用…

【JAVA】第三张_Eclipse下载、安装、汉化

简介 Eclipse是一种流行的集成开发环境&#xff08;IDE&#xff09;&#xff0c;可用于开发各种编程语言&#xff0c;包括Java、C、Python等。它最初由IBM公司开发&#xff0c;后来被Eclipse Foundation接手并成为一个开源项目。 Eclipse提供了一个功能强大的开发平台&#x…

IDEA如何查看所有的断点(Breakpoints)并关闭

前言 我们在使用IDEA开发Java应用时&#xff0c;基本上都需要进行打断点的操作&#xff0c;这方便我们排查BUG&#xff0c;也方便我们查看设计的是否正确。 不过有时候&#xff0c;我们不希望进入断点&#xff0c;这时候除了点击断点关闭外&#xff0c;有没有更快速的方便关闭…

深度解析机器学习的四大核心功能:分类、回归、聚类与降维

深度解析机器学习的四大核心功能&#xff1a;分类、回归、聚类与降维 前言分类&#xff08;Classification&#xff09;&#xff1a;预测离散标签的艺术关键算法与代码示例逻辑回归支持向量机&#xff08;SVM&#xff09; 回归&#xff08;Regression&#xff09;&#xff1a;预…

HarmonyOS Next应用开发——图像PixelMap变换

【高心星出品】 图像变换 图片处理指对PixelMap进行相关的操作&#xff0c;如获取图片信息、裁剪、缩放、偏移、旋转、翻转、设置透明度、读写像素数据等。图片处理主要包括图像变换、位图操作&#xff0c;本文介绍图像变换。 图形裁剪 // 裁剪图片 x&#xff0c;y为裁剪的起…

impdp+remap_schema导入后登录报ORA-01017: Invalid Username/password

环境说明&#xff1a;有个11.2.0.4的rac数据库&#xff0c;现需要把USR_OA克隆一份出来做测试&#xff0c;新用户名是TEST_OA&#xff0c;直接是expdp导出用户&#xff0c;再用impdpremap_schema生成TEST_OA&#xff0c; 业务人员使用PLSQL(版本12.0.1.1814) 登录TEST_OA时总…

Python程序设计 内置函数 日志模块

logging(日志) 日志记录是程序员工具箱中非常有用的工具。它可以帮助您更好地理解程序的流程&#xff0c;并发现您在开发过程中可能没有想到的场景。 日志为开发人员提供了额外的一组眼睛&#xff0c;这些眼睛不断关注应用程序正在经历的流程。它们可以存储信息&#xff0c;例…

ShardingProxy服务端分库分表

目录 一、为什么要有服务端分库分表&#xff1f; 二、ShardingProxy基础使用 1、部署ShardingProxy 2、配置常用分库分表策略 三、ShardingSphere中的分布式事务机制 1、什么是XA事务&#xff1f; 2、实战理解XA事务 3、如何在ShardingProxy中使用另外两种事务管理器&a…

【不要离开你的舒适圈】:猛兽才希望你落单,亲人总让你回家,4个维度全面构建舒适圈矩阵

单打独斗的英雄时代已经落幕 抱团取暖才是社会寒冬的良策 自然界中&#xff0c;每个物种都占据着自己的领地和生存空间。 生态位的差异决定了它们的生存方式&#xff0c;一旦离开领地&#xff0c;失去群体的庇护&#xff0c;就会沦为野兽的美餐。 人类社会同样存在隐形圈层…

数仓建模:金字塔原理在数仓建模分析中的应用

目录 1 金字塔原理 1.1 金子塔原理基本原理 1.2 金字塔内部结构 2 如何构建金字塔 2.1 金字塔塔尖构建 2.2 金字塔纵向层次构建 2.3 金字塔横向关系构建 2.3.1 归类分组 2.3.2 逻辑递进 2.4 小结 3 金字塔原理应用 3.1 数仓建模 3.1.1 数仓建模分析方法-自上而下…

OBOO鸥柏:液晶拼接大屏搭载节点盒分布式集中管控控制系统新技术

近年来&#xff0c;随着视频监控、会议系统及展示需求的快速增长&#xff0c;KVM分布式输入输出节点控制系统在各大行业中逐渐成为核心技术。OBOO鸥柏的液晶拼接大屏分布式输入输出节点控制系统&#xff08;WControl&#xff09;&#xff0c;以其创新的技术和卓越的用户体验&am…

在线刷题系统测试报告

一、项目背景 1. 本项目是一个在线刷题系统&#xff0c;灵感来源于力扣和牛客等刷题平台&#xff0c;旨在锻炼自己的代码能力和剖析系统整体结构与各模块之间关系的能力。系统支持用户注册与登录&#xff0c;查看题目列表与题目详情&#xff0c;在线提交代码并提供反馈。 2. 该…

【命令操作】信创终端系统上timedatectl命令详解 _ 统信 _ 麒麟 _ 方德

原文链接&#xff1a;【命令操作】信创终端系统上timedatectl命令详解 | 统信 | 麒麟 | 方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于如何在信创终端系统上使用timedatectl命令的详细介绍。timedatectl 是Linux系统中非常实用的时间管理工具&#xff0c;…

JMeter模拟并发请求

PostMan不是严格意义上的并发请求工具&#xff0c;实际是串行的&#xff0c;如果需要测试后台接口并发时程序的准确性&#xff0c;建议采用JMeter工具。 案例&#xff1a;JMeter设置20个并发卖票请求&#xff0c;查看后台是否存在超卖的情况 方式一&#xff1a;一共10张票&…

大数据-177 Elasticsearch Query DSL - 聚合分析 指标聚合 桶聚合

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Excel重新踩坑3:条件格式;基本公式运算符;公式中的单元格引用方式;公式菜单栏其他有用的功能说明;

0、前言&#xff1a;以下内容是学习excel公式的基础内容。 1、需求&#xff1a;将表格特定区域中数值大小大于等于30&#xff0c;小于等于80的单元格&#xff0c;颜色填充为红色&#xff0c;大于80的&#xff0c;颜色填充为黄色。 新建规则之后也可以通过该功能清除规则。 2、基…

【JavaEE初阶】网络编程TCP协议实现回显服务器以及如何处理多个客户端的响应

前言 &#x1f31f;&#x1f31f;本期讲解关于TCP/UDP协议的原理理解~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废话不多说…

【重学 MySQL】六十六、外键约束的使用

【重学 MySQL】六十六、外键约束的使用 外键约束的概念关键字主表和从表/父表和子表外键约束的创建条件外键约束的特点外键约束的创建方式外键约束的删除外键约束的约束等级外键约束的级联操作外键约束的示例外键约束的作用开发场景阿里开发规范 在MySQL中&#xff0c;外键约束…

免费开源的微信开发框架

近年来&#xff0c;随着人工智能技术的快速发展&#xff0c;聊天机器人在各个领域得到了广泛的应用。在社交媒体中&#xff0c;自动回复成为了一个流行的功能&#xff0c;让用户可以方便地与机器人进行互动。gewe框架&#xff0c;一个开源的微信聊天机器人框架&#xff0c;实现…