c#:主窗体与子控件之间的数据传递:基于事件和委托的实现

news/2025/3/18 4:33:11/

1. 概述

在WPF中,主窗体与子控件之间的数据传递通常通过以下两种方式实现:

事件(Event):主窗体触发事件,子控件订阅事件并接收数据。

委托(Delegate):通过委托将子控件的方法传递给主窗体,主窗体调用委托来传递数据。

本文的示例代码展示了如何通过事件和委托实现主窗体向子控件传递数据的过程。

2. 关键技术点

2.1 事件(Event)

事件是一种特殊的委托,用于在对象之间传递消息。主窗体可以通过事件将数据传递给订阅了该事件的子控件。

2.2 委托(Delegate)

委托是一种类型安全的函数指针,可以将方法作为参数传递。在主窗体中,通过委托调用子控件的方法来传递数据。

2.3 数据传递流程

主窗体通过TcpClient接收数据。

主窗体触发事件,将数据传递给订阅了事件的子控件。

子控件处理接收到的数据并更新UI或执行其他逻辑。

3. 代码实现

以下是基于事件和委托实现主窗体向子控件传递数据的代码示例。

3.1 主窗体(MainWindow)

主窗体负责接收数据并通过事件将数据传递给子控件。

public partial class MainWindow : Window
{// 定义事件,用于传递数据public event Action<byte[]> DataReceived1;public event Action<byte[]> DataReceived2;// 其他事件...// 定义委托,用于发送数据public SendDataDelegate1 SendData1Delegate { get; set; }public SendDataDelegate2 SendData2Delegate { get; set; }// 其他委托...public MainWindow(){InitializeComponent();// 初始化委托SendData1Delegate = new SendDataDelegate1(SendData1);}// 发送数据的方法public void SendData1(byte[] message){string errorMsg = string.Empty;if (isConnected1){tcpClient1.SendData(message, out errorMsg);}}// 接收数据的方法private void ReaceiveData(){while (true){try{bool result = false;string errorMsg = string.Empty;byte[] readReadBytes = tcpClient1.ReceiveData(out result, out errorMsg); // 接收数据if (readReadBytes != null){// 触发事件,将数据传递给订阅者DataReceived1?.Invoke(readReadBytes);}}catch (Exception ex){Console.WriteLine($"Failed to connect to power supply: {ex.Message}");}if (isConnected1 == false){break;}}}
}

3.2 子控件(MainUserControl)

子控件订阅主窗体的事件,并在事件触发时处理接收到的数据。

public partial class MainUserControl : UserControl
{// 定义委托private SendDataDelegate1 SendData1;// 连接状态public bool _isConnected1 { get; set; }// 接收到的数据public byte[] GetReceived1 = null;public MainUserControl(SendDataDelegate1 sendData1, bool isConnected1){InitializeComponent();SendData1 = sendData1;_isConnected1 = isConnected1;// 获取主窗体实例并订阅事件var mainWindow = Application.Current.MainWindow as MainWindow;if (mainWindow != null){mainWindow.DataReceived1 += MainWindow_DataReceived1;}}// 事件处理方法private void MainWindow_DataReceived1(byte[] data){if (Controls.Count > 0){var controlBox = Controls.FirstOrDefault(cb => cb.id == 1);if (controlBox != null){string boxip = controlBox.IP;List<string> DevName = GetDevInfo(boxip); // 刷新设备信息if (data != null && data[8] == 0x50){GetReceived1 = data;int receiveDataLength = (GetReceived1[4] * 256) + GetReceived1[5] - 3; // 计算有效数据长度byte[] receiveDataBuffer = new byte[receiveDataLength];Array.Copy(GetReceived1, 9, receiveDataBuffer, 0, receiveDataLength); // 复制有效数据ushort[] message = modbusInstance.GetUnitsFromByteArray(receiveDataBuffer); // 解析数据DevMathData(message, DevName, boxip); // 处理数据}}}}
}

4. 数据传递流程详解

4.1 主窗体接收数据

主窗体通过TcpClient接收数据。

接收到数据后,主窗体触发DataReceived1事件,并将数据作为参数传递给订阅者。

4.2 子控件订阅事件

子控件在构造函数中获取主窗体实例,并订阅DataReceived1事件。

当主窗体触发DataReceived1事件时,子控件的MainWindow_DataReceived1方法会被调用。

4.3 子控件处理数据

子控件在MainWindow_DataReceived1方法中解析接收到的数据。

根据数据内容更新UI或执行其他逻辑。

  1. 关键技术解析

5.1 事件的订阅与触发

订阅事件:子控件通过mainWindow.DataReceived1 += MainWindow_DataReceived1订阅主窗体的事件。

触发事件:主窗体通过DataReceived1?.Invoke(readReadBytes)触发事件,并将数据传递给子控件。

5.2 委托的使用

主窗体通过SendData1Delegate调用子控件的方法,实现数据发送。

子控件将方法传递给主窗体,主窗体在需要时调用该方法。

5.3 数据的解析与处理

子控件通过modbusInstance.GetUnitsFromByteArray解析接收到的数据。

解析后的数据用于更新UI或执行其他业务逻辑。

6. 总结

本文详细介绍了如何通过事件和委托实现主窗体与子控件之间的数据传递。通过事件,主窗体可以将数据传递给订阅了事件的子控件;通过委托,子控件可以将方法传递给主窗体,实现双向通讯。这种设计模式不仅提高了代码的可维护性,还增强了模块之间的解耦性。

希望这篇文章对您有所帮助!如果有任何问题,欢迎在评论区留言讨论。


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

相关文章

【MySQL】多表查询(笛卡尔积现象,联合查询、内连接、左外连接、右外连接、子查询)-通过练习快速掌握法

在DQL的基础查询中&#xff0c;我们已经学过了多表查询的一种&#xff1a;联合查询&#xff08;union&#xff09;。本文我们将系统的讲解多表查询。 笛卡尔积现象 首先&#xff0c;我们想要查询emp表和stu表两个表&#xff0c;按照我们之前的知识栈&#xff0c;我们直接使用…

本地部署Deep Seek-R1,搭建个人知识库——笔记

目录 一、本地部署 DeepSeek - R1 1&#xff1a;安装Ollama 2&#xff1a;部署DeepSeek - R1模型 3&#xff1a;安装Cherry Studio 二、构建私有知识库 一、本地部署 DeepSeek - R1 1&#xff1a;安装Ollama 1.打开Ollama下载安装 未科学上网&#xff0c;I 先打开迅雷再下…

大语言模型在生成文章摘要、新闻标题领域的应用

大语言模型&#xff08;LLM&#xff09;在文章摘要和新闻标题生成领域已形成多个成熟应用&#xff0c;这些应用通过提升效率、优化质量和适应复杂场景&#xff0c;显著改变了内容处理的方式。以下是具体应用场景及技术特点的总结&#xff1a; 一、文章摘要的成熟应用 自动生成…

Windows10 WSL又又又一次崩了 Docker Desktop - Unexpected WSL error

问题&#xff1a;Windows10 WSL又又又一次崩了 这回报错&#xff1a; 然后再打开WSL Ubuntu就卡住了&#xff0c;等很长时间没反应&#xff0c;就关掉了。 手动启动Docker Desktop&#xff0c;报错&#xff1a; An unexpected error occurred while executing a WSL comman…

DeepSeek-R1:开源大模型的技术革命与行业影响分析

一、发布背景与开发者定位 DeepSeek-R1由幻方量化旗下AI公司深度求索&#xff08;DeepSeek&#xff09;于2025年1月20日正式发布&#xff0c;标志着中国AI公司在生成式大模型领域取得突破性进展。该模型的推出具有多重战略意义&#xff1a; 技术突破性&#xff1a;作为全球首…

CF 230B. T-primes

题目 time limit per test&#xff1a;2 seconds&#xff1b;memory limit per test&#xff1a;256 megabytes We know that prime numbers are positive integers that have exactly two distinct positive divisors. Similarly, well call a positive integer t Т-prime,…

麒麟系统使用-安装 SQL Developer

文章目录 前言一、基础准备1.基本环境2.相关包下载 二、进行相关配置1.配置JAVA2.配置SQL Developer 总结 前言 作为我国自主研发的操作系统&#xff0c;麒麟系统在使用时需要考虑安装相应的app。尽管麒麟系统是基于linux开发&#xff0c;可由于版本的一些差异&#xff0c;麒麟…

JVM常用概念之超态虚拟调用

问题 超态虚拟调用是什么? 基础知识 大部分认为超态调用是非常糟糕的&#xff0c;主要是因为超态调用会调用慢路径&#xff0c;并且无法享受编译器优化&#xff0c;那OpenJDK可以取消超态调用吗?那在发生超态调用时我们可以做什么呢? 实验 源码 import org.openjdk.jm…