基于BREW平台松耦合设计IV-重构AlarmService的整体设计

Windows10系统添加虚拟网卡(Microsoft Loopback Adapter)的方法 1、按下win + R键,在其中输入:hdwwiz,然后 (enter) 2、点击下一步即可 3、其次选择【网络适配器】,然后点击【下一步】。 4、在厂商处选择Microsoft,网络适配器处选择【Microsoft Loopback Adapter】选项 ,点击【下一步】。 5、通过上面几个步骤的设置后,一块虚拟网卡的安装设置就算是完成了。 ... 阅读详情

 

基于BREW平台松耦合设计IV-重构AlarmService的整体设计

毛晓冬 2008-5-6

 

一、           概述:

本文主要通过一个实际模块的改善过程,感性的体现设计原则的使用。

 

二、           目前的AlarmService框架:

 

目前的AlarmService主要包括两个模块,AlarmApp,TodoApp。AlarmApp主要负责闹铃(包括自动关机,关机闹铃)功能,TODO主要负责类似日程提醒的功能。随着需求的增多,目前这两个模块其实比较复杂。目前的整体设计框架如下:

 

 

 

 

AlarmApp负责UI的显示,Alarm的设置,过期处理,计算下一个Alarm,存取Alarm的持久性数据。

TODO和AlarmApp类似。这里可以看到,AlarmApp和TODOApp模块内部直接完成了所有的逻辑。

我们再看看模块间的交互(按上图的序号):

1.  日程提醒到期后,TODOApp通过发送Event给EventBox,由EventBox来弹出日程提醒框。

2.  SettingApp中可以设置自动关机闹铃,SettingApp通过发送Event给AlarmApp,由AlarmApp来最终设置该自动关机的闹铃,使得闹铃的控制完全由Alarm负责。

3.  闹铃到期后,AlarmApp通过发送Event给EventBox,由EventBox来弹出闹铃提醒。在EventBox界面,当用户选择Snooze或者关闭时,EventBox再发送Event通知AlarmApp应该Snooze还是关闭。

4.  当AlarmApp中不存在Active闹铃时,AlarmApp会发送Event给TODOApp询问是否TODOApp也不存在Active的日程。TODOApp通过回Event的方式告知结果。如果TODOApp也无Active日程时,AlarmApp发送Event给CoreApp通知清除系统栏的闹铃图标。 当TODOApp中不存在Active日程时,处理类似。

5.  AlarmApp使用BREW的AlarmService提供的API。同时,BREW以Event方式通知AlarmApp闹铃的过期。

6.  TODOApp通知CoreApp清除闹铃系统栏(见4)

7.  TODOApp使用BREW的AlarmService提供的API。同时,BREW以Event方式通知TODOApp日程的过期。

8.  AlarmApp通知CoreApp清除闹铃系统栏(见4)

 

三、           目前框架的缺点:

1.  紧耦合:这里存在两个紧耦合,一是模块内的紧耦合,一是模块间的紧耦合。

a.  模块内的紧耦合:AlarmApp/TODOApp应用代码内部完成了包括UI显示,设置Alarm,日程,处理过期,存储数据等等的所有任务。整个显得较乱。导致某一方面的变化(更改,比如UI的)影响到整个应用,不得不更改整个应用。牵一发而动全身,稍有不慎,无关联的方面也会受牵连,出现问题。不仅如此,模块内的紧耦合还导致代码逻辑混乱,不利于维护,更加不利于新人的阅读和掌握。

b.  模块间的紧耦合: 如上面的框图,可见多个模块间直接使用Event方式通信,在编译期就绑定在了一起,呈现出网状(多 对 多)的耦合。这种模块间的紧耦合,导致单个模块的变化可能不期望的影响到其他模块,并且也使得代码逻辑混乱,不利于维护,也不利于新人的阅读和掌握。

2.  低复用:其实TODOApp和AlarmApp两个模块除了UI的差别比较大外,内部的逻辑处理(如何设置alarm,如何处理Alarm到期等等)以及持久性数据的存储都基本一样,完全可以复用。但目前的方案下,完全由两个模块重复的独立自己实现一套。

3.  不易扩展:扩展性是和耦合性密切相关的,耦合的如此紧密,那基本上就只能是“修改”,而不是扩展了。

4.  难以抵抗变化:需求往往带动变化,永恒不变的就是“变化”。所以,一个设计的好坏,就是看它是否能抵抗可预见的变化。变化只有被各自独立的封装起来后,才有可能抵抗变化,因为此时一个变化点不会影响到另一个不变点。而目前的设计,模块间和模块内的紧密耦合,根本无法抵抗变化。UI的需求变化,导致直接更改整个App,业务逻辑的变化,也导致更改整个App。

 

四、           如何逐一改善:

1.  利用三层结构解决模块内的紧耦合:

从上面的分析可以看到,模块间的耦合主要是由于把所有逻辑都混在一起了,没有分层处理。当进行分层处理后,就可以区分不同的逻辑,进而就可以封装并隔离变化点,让每一部分的变化独立的进行。

以抽象的观点来看AlarmApp或者TODOApp模块,存在3个独立的变化点,UI,内部逻辑,数据存取。由此,我们可以将其分解为UI逻辑,业务逻辑,数据访问三层,或言之3个变化点。分解之后,就是封装,封装之后,各个变化点的变化就不再会影响其他部分了。

这里UI逻辑以应用形式实现,即App只负责UI。

业务逻辑以扩展接口独立,IAlarmEx,负责AlarmService相关的业务逻辑,内部访问数据访问接口,对外提供: 获取Alarm状态,设置Alarm,Alarm过期后的自动处理,Snooze处理等等

                     数据访问以接口独立(目前使用IDataBase)负责持久性数据的存取。

 

2.  利用中介者(Mediator)方式解决模块间的紧耦合:

原有的模块间都是直接交互(事件方式),体现出网状。这是紧耦合的根源。

可以试着引入中央控制层,所有模块都只和中央控制层交互,由中央控制层“代劳”与目的模块交互。 从而,将多 对 多的关系, 简化为 多 对 一的关系, 便于控制。 这种降低多 对 多之间的耦合方式, 其实就是 中介者(Mediator) 方式。

当将IAlarmEx设计成一个公共接口提供AlarmService的业务逻辑时, IAlarmEx就是一个中介者。 所有的模块,现在都只和IAlarmEx接触,IAlarmEx内部直接消化相应的业务逻辑处理,除非必要时,IAlarmEx才会和其他目的模块交互。

 

3.  解决低复用:

由于IAlarmEx是一个公共的业务逻辑接口,TODO 和 Alarm基本只是UI的差异, 所以, TODO可以完全复用IALARMEx接口。

 

4.  解决可扩展:

由于分层,封装了变化点,使得扩展性增强了,即,在不改变原有整体代码的基础上,扩展功能。

 

5.  数据的透明传输:

原本的某些模块间传递特殊的App-Spec 数据,比如AlarmApp需要将当前到期的AlarmID,铃声文件路径等信息传递给EventBox,TODOApp则必须把日程内容传递给EventBox。这些数据,都属于UI逻辑范畴,进一步讲,属于通信的端点的范畴。必须对中介者,或者说业务逻辑而言是透明的,否则,随着通信端点Spec的变化,或者UI逻辑的变化,就会使得中介者,或者业务逻辑也产生不期望的变化。为了隔离这种变化,我们引入了数据的透明传输,即IAlarmEx接口提供设置Alarm,或者Add一个日程时,API的最后一个参数为VOID*的透明数据,IAlarmEx只负责存储该透明数据,并当Trigger时,把该透明数据传递给Destination,比如EventBox,至于究竟是什么数据,一无所知,在通信的发,收方,完成数据的封装和提取,其实就是一个VOID*向特殊指针的转换。其实,这和OSI的7层协议很类似,底层接口向上层接口服务,并且完成数据的透明传输。

 

6.  使用Adaptor:

我们分层后的设计,其实和平台是无关的。但是,因为我们运行在具体的平台上,所以往往可能出现平台所期望的接口和我们设计的接口不一致,此时我们就需要一个Adaptor。

在我们的新的设计方案中,一切业务逻辑都是在IAlarmEx中完成,包含Alarm到期后的处理,完全不需要和其他模块相关联。但是,BREW平台的AlarmService必须存在一个App的载体,因为其设置Alarm时,必须指定App的CLSID,即,Alarm是为App设置的,而不是接口。同样的,当Alarm到期后,BREW通知的是App,而不是接口。

 

不过不要紧,这种差异性,我们只需要引入一个Adaptor即可。基于BREW的限制,该Adaptor必须是一个App。因为,我们同时设计了一个AlarmDaemon App,主要就是完成Adaptor的功能,即,IAlarmEx的实现中,当设置Alarm时,使用AlarmDaemon的CLSID(将其作为载体)。Alarm过期后,AlarmDaemon App收到通知,此时其处理非常简单,直接调用IAlarmEx_Trigger API即可。通过AlarmDaemon的Adaptor功能,使得其他任何模块,都没有被关联进不该关联的业务逻辑中来。

 

 

五、           重构后的新框架:

 

 

 

基于前面的描述和上面的框图,大家应该对重构后的新方案比较熟悉了。这里再说明一下,基于重构后的新方案,原有的场景,现在变得多么简单(按序号):

1.  日程提醒或者闹铃到期后,IAlarmEx_Trigger被调用,内部计算下一个闹铃并设置后,就会自动的通知EventBox,并传递相应的透明数据。EventBox弹出提示框。当用户选择SNOOZE时,EventBox调用IAlarmEx_Snooze即完成了Snooze闹铃的设置。

2.  SettingApp通过调用IAlarmEx_SetAlarm来设置自动关机闹铃,同时可以调用IAlarmEx_SetSnoozeMode来更改Snooze Mode的Value。

3.  AlarmApp通过调用IAlarmEx_GetXXX来获取Alarm数据并在UI上显示,当用户设置,取消Alarm时,调用IAlarmEx_Set/CancelAlarm。

4.  TODO和AlarmApp类似。

5.  IAlarmEx内部使用BREW的AlarmService API

6.  对于自动关机闹铃到期后,IAlarmEx内部通知CoreApp并传递透明数据,CoreApp实现关机。此外,当IAlarmEx监测到没有任何Active TODO和 Alarm存在时,则会通知CoreApp去除系统栏的Alarm标志。

7.  AlarmDaemon作为Adaptor App充当载体,接收BREW AlarmService的通知,并委托给IAlarmEx处理。

8.  Alarm到期后BREW AlarmService通知AlarmDaemon App

 

需要注意的是,框架中的IAlarmEx主动和其他模块间的交互,是通过事件的方式。但却不是在编译期绑定的,即没有使用硬编码的CLSID,而是使用了BREW的MIME Handler机制,在运行时动态的绑定,从而解除了通信时的耦合。

 

六、           如何抵抗需求的变化:

逻辑被分离了,变化点被封装了。从而可以抵抗需求的变化。比如:

新项目对UI的要求较高,此时只需要更改UI逻辑即可,完全不会影响到业务逻辑。

新项目要求支持关机闹铃,并且支持时间可设置,此时只需亚更改IAlarmEx,即业务逻辑,完全不影响应用。

新项目要求EventBox显示闹铃时更加个性化,显示的风格可以定制。此时,只需要更改AlarmApp和EventBox的“通信协议”,由于IAlarmEx使用了数据透明传输,所以此时并不影响IAlarmEx,即不影响业务逻辑。

新项目要求使用新员工接手该模块,不用怕,新员工2天内就理顺了代码 J

 

七、           总结:

本文通过对现有的AlarmService的框架提出缺点,并且讲解如何一步步解决问题,最终重构得到一个新的框架,感性的摄入了一些重要的软件设计思想,希望对大家有帮助。

注意:本文仅从理论上描述了一个重构的方案,至于新方案是否会在新项目或者新平台中使用,这个和具体的实施进度,项目进度有关。目前来看,由于前期的实现,验证,移植尚未完全完成,所以在6055上使用的可能性也并非100%。

 

 


CoppeliaSim+matlab+simulink七轴机械臂仿真 七轴机械臂vrep+matlab+simulink 仿真 阅读详情

相关推荐

手把手教你用Cesium和RayMarching实现逼真体积云(附完整Shader代码)

本文详细介绍了如何利用Cesium和RayMarching技术实现逼真的体积云效果,包括环境准备、核心逻辑、云层建模和光照增强等关键步骤,并提供了完整的Shader代码。通过噪声函数选型、动态风场模拟和多重散射近似等技术,开发者可以在数字地球可视化项目中创建沉浸式天气效果,显著提升场景的真实感。

weixin_29230649的博客 415

Alarm

标题1. Alarm alarm模块是处理报警event的,judge产生的报警event写入redis,alarm从redis读取处理 1.1. 设计初衷 报警event的处理逻辑并非仅仅是发邮件、发短信这么简单。为了能够自动化对event做处理,alarm需要支持在产生event的时候回调用户提供的接口;有的时候报警短信、邮件太多,对于优先级比较低的报警,希望做报警合并,这些逻辑都是在alarm中做的。 我们在配置报警策略的时候配置了报警级别,比如P0/P1/P2等等,每个及别的报警都会对应不同的red

jixu8的博客 591

uniapp实现app版本发现新版本后,自动更新

app实现自动更新

oldolder的博客 1283

IPC(进程间通信),Remote Call(远程调用),IDL(接口描述语言)架构及其在BMP(BREW移动平台),Android中的应用浅析

<br /><br />由于本人才初识BMP和Android,所以仅仅是自己的一些肤浅认识,难免有错误,欢迎指正。<br /> <br />首先我们看IPC,现代操作系统都是多进程,多线程的。进程间存在地址边界,无法直接跨越。所以,两个进程间无法进行直接的请求,传递和调用。IPC是操作系统内核提供的一种跨进程的机制,允许两个进程间使用IPC来传递数据。 虽然某些情况下我们可以将Service直接加载到自己的进程中调用服务,此时可以进行简单的本地调用(Local Call),但是,从安全,性能和共享的角度出发

东方欲晓的专栏 3749

【Godot】实现对话系统

在 Godot 中实现对话系统(Dialogue System)是游戏开发中的常见需求。Godot本身自带的的灵活性和轻量级脚本语言 GDScript 使得实现对话系统变得相对简单。以下是实现一个基础对话系统的示例。(语言为GDScript但高亮选择Python因为类似)通过 Godot 和 GDScript,我们可以给我们的游戏实现一个对话系统。从简单的文本显示到复杂的分支对话,Godot 提供了足够的灵活性来满足我们的需求。如果需要更高级的功能,可以尝试使用现成的插件如 Dialogic。

Octopus2077的博客 2519

架构——异地多活成熟的架构模式

摘要: 本文系统介绍了三种异地多活架构模式:业务定制型、业务通用型和存储通用型。业务定制型针对核心业务定制化设计,复杂度低但扩展性差;业务通用型通过统一配套服务(流量调度、配置中心等)实现多业务兼容,适合业务量大但一致性要求不高的场景;存储通用型依托分布式一致性数据库(如OceanBase、TiDB)天然支持强一致性,适合金融等高要求场景,但对部署距离和成本有较高限制。文章对比了各模式的优缺点及适用场景,为不同业务需求下的架构选型提供了实践指导。

小志的博客 7084

BREW Notify机制使用注意点

<br /><br />BREW Notify机制使用注意点<br />毛晓冬<br />2007-10-12<br />一、注册Notify的注意点:<br />       a. 注册方式:<br />BREW中有两种注册Notify的方式,一种是在MIF文件中Add Notification,一种是在代码中通过调用ISHELL_RegisterNotify来显式的注册Notify。MIF文件中注册的Notify,从BREW初始化后就开始生效,所以从此刻开始,App就可以收到Notification,即

东方欲晓的专栏 1626

Halcon Socket TCP通讯:从算子调用到工业视觉系统集成

本文详细介绍了Halcon Socket TCP通讯在工业视觉系统中的应用与优化技巧。从基础算子调用到高并发处理,再到与PLC、机器人及MES系统的集成实战,提供了全面的解决方案和性能优化建议,帮助开发者高效实现工业视觉系统的通讯需求。

weixin_33502772的博客 248

比较BMP和Android的RPC机制

RPC机制是现代系统的重要的一种机制,和IPC有关,却又没有必然关系。 RPC是更广义的,更高层的,为解决异构/非本地对象/过程调用而形成的一套解决方案,其目的重在解决如何让远程对象/过程的访问可以如同本地对象/过程那般,将真正的差异性向上层客户隐藏。   而IPC仅仅是

东方欲晓的专栏 1502

攻克TypeError: Cannot read properties of undefined (reading ‘NormalModule‘)的四种实战策略

本文详细解析了`TypeError: Cannot read properties of undefined (reading 'NormalModule')`错误的四种实战解决策略。从版本一致性检查、包管理器优化到依赖替换和构建环境配置,帮助开发者快速定位和解决Webpack构建过程中的常见问题,提升开发效率。

weixin_42523670的博客 242

非机动车闯红灯检测与自动录像系统实战(YOLO+追踪+红绿灯感知)

本文聚焦非机动车(如电动车、自行车)闯红灯行为的智能识别系统构建,结合 YOLO 检测模型、追踪算法(如 DeepSORT)、红绿灯状态感知与区域判断逻辑,构建完整的违章行为识别与证据录像系统。文章涵盖数据采集、模型选型、红绿灯触发机制、闯红逻辑判定、视频自动保存等核心环节,辅以 Jetson/RK3588 平台部署与工程实测,适用于城市交通监控、智慧路口管控等真实场景。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 1285

BREW与面向对象的比较

<br /><br />BREW与面向对象的比较<br />毛晓冬2007-6-13<br />一、    概述:<br />虽然BREW的整体框架是基于接口体系,是面向对象的。但是和C++,C#,Java不同,这些语言的面向对象是语言(编译器)层次上的支持,而BREW的面向对象是实现层次上的支持(BREW的框架是以纯C实现面向对象的体系)。由于支持的层次不一样,所以仍然存在着很大的差异性。<br />我们有必要了解这些差异性,不能直接拿传统面向对象语言的特性来同等的看待BREW,那样有时可能存在偏差,可

东方欲晓的专栏 1359

Vue2 - 详细实现接入使用海康威视监控云端显示及控制功能,网站集成安装海康监控及实时监控显示、回放、放大缩小画面、视频画面截图、截屏抓拍、摄像头控制,实时推流及播放器解决延迟卡顿等问题(详细代码)

vue2,nuxt2,海康威视,海康监控,摄像头监控,vue对接海康处理接口认证规则,监控实时预览和回放功能,海康api接口,安全认证,海康开放平台,官方文档,播放海康摄像头的监控视频,海康实时监控播放详细步骤,web,黑屏,特别卡不流畅怎么办,解决无法推流,录像,连接不上,vue,海康,vue海康视频监控,海康开放平台,实时监控画面,海康插件,视频播放,回放,视频流地址,取流协议,视频sdk播放,hik,rtsp,rtmp,hls,ws,网站,网页,h5页面,后台管理系统,vue2对接海康监控设备,无法连

🏆 前端领域优质创作者 8245

BREW(包括BUIW)引用计数及内存使用规则

<br /><br />BREW(包括BUIW)引用计数及内存使用规则<br />毛晓冬2007-1-26<br /> <br />一、概述:<br />BREW使用COM的引用计数机制在多个客户间同时共享一个接口的实例,保证各个客户在使用期间,该接口实例始终有效,而不管其他客户是否已经使用完该接口实例。只有当所有客户都结束使用时,该接口的实例才会被释放。<br />该机制使得我们必须正确操作接口的引用计数,否则会造成内存泄漏,或者重复释放等严重问题。<br />所以,我们需要掌握引用计数的使用规则和注意点

东方欲晓的专栏 1280

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

BREW和Android的安全思想

<br /><br />理论上,所有的公众(公开)实体,都需要安全机制保障, 比如网络。 从分层角度而言,每一层都可以进行安全保护,比如网络协议中的IpSec(Ip层), SSL(传输层), sMIME(应用层)安全协议。 对于移动平台也不例外, 也可以在不同的层次进行安全保障,系统底层和框架上层。<br /> <br />对于BREW平台,一直就是非智能的平台,所以它对底层系统的奢求不是那么高,无需任何现代操作系统的支持。 所以, BREW也就不能对系统层的安全做任何奢求,那么只能完全在BREW这一层实现

东方欲晓的专栏 1159

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

爱之深,期之切, 历数BREW几宗“罪”

本文不是敌人之间的奚落,谩骂。是爱人之间的激励。 那种感觉,是“只允许我1天骂他8次,却容不得别人说他一次不好”。那是因为爱她,所以希望她更好,走的更远。 所以,冒昧的写下本文,提出一些个人感觉BREW有待改进,完善的地方。1。 过于封闭,技术资源匮乏。      对于BREW,除了来自官方的SDK外,似乎找不到任何权威的技术资料和文档。1年,2年,3年过去了,还是这样。 看看后起之秀, IPhone,Android, 不管是来自民间的,还是来自官方,权威的资料,书籍,比比皆是,不管是深入的,还是浅出的。

东方欲晓的专栏 1131

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

BREW你问我答

发布该贴的唯一目的是尽我绵薄之力,在我有限的知识范围和能力范围内,解答部分网友brew方面的问题。有任何brew相关问题的TX,都可以在该贴的评论处提问,只要我能力范围内的,我将尽力解答。 闲话不多了,有问题的可以提。

东方欲晓的专栏 1068

BREW与Android中的UI事件框架比较

对于BREW,我非常熟悉,但是对于Android,只能算刚刚认识,最近看了些Android的UI事件处理的相关文档,发现Android的UI事件处理框架与BREW有一些异同,这里给予一些比较,纯属个人认识。 如有不当之处,欢迎指正。相同之处在于,从高层而言,Android与BREW的UI事件框架均是基于职责链模式的,运行时构成了Event Chain。 Event Chain中的每一个部件默认将事件传递给后继者。 事件在Event Chain的终点处自然终止, 或者在中间异常终止(中间部件返回了TRUE,导

东方欲晓的专栏 1010

【BREW你问我答】02期_20100709

为了使得BREW你问我答办的更好,决定不再在一个帖子中靠不断的回复来问答,这样多了后比较乱。 以后,基本上每周我会更新一期, 大家每次的新问题,请都在最新期的BREW你问我答(会置顶)中提问。 我一般只会关注最新期的问题。  当然,对于老问题的继续探讨,可以在原先的提问的基础上再提问谢谢~~~~~新的问题请在本帖子下开始提问

东方欲晓的专栏 1002

More Than BREW: 解析BREW核心机制

More Than BREW: 解析BREW核心机制 的提纲

东方欲晓的专栏 991

移动平台中的模块复用

在“复用”这一角度,无疑android是最棒的,至少到目前尚无平台可以出其右。 当然,我相信android的思想也不是一蹴而就的,也是借鉴并发展了前人的思想。 我们慢慢看来:     1. 首先,在Windows等PC平台上,最常见的复用的粒度 是基于 “进程”的复

东方欲晓的专栏 977

CS(Component Service), BMP(Brew Mobile Platform)那点事

<br />大家知道Qualcomm最新的BREW版本为BMP,BMP又是基于CS的,那么为何要演进到BMP,以及BMP为何需要基于CS那,其实,这个还是有一个背景的, 本文主要就笔者的观点,谈谈我所认为的背景。<br /> <br /> <br />BREW从1.0一直发展到3.x,一直充当着Feature Phone中的平民英雄的角色, 它的优点,就是可以不依赖于(不奢望)底层平台/系统的现代特性(多进程,多线程,内存保护,动态链接,动态加载等)而依靠自身实现一个轻量级的应用框架,同时支持动态加载。 所

东方欲晓的专栏 962

Android, BREW中Observer(观察者)模式的两种表现

Observer模式无疑是最伟大的设计模式之一。 她被用来解耦一对多的关系,并对“多”的变化进行隔离。 现代移动平台中,各是随处可见她的身影。 本文将从Android,BREW两个移动平台中,一窥其迷人身姿。Listener机制。 在BREW和Android中,同时都提供了Listener机制。这是血统纯正的Observer模式体现。 BREW中的IModel的AddListener和Android中的View的AddXXXListener就是两个很好的例子。 在这种纯种Observer模式下,我们需要明确

东方欲晓的专栏 901

BREW事件使用技巧: 避免事件冲突

详述了BREW中事件定义的注意点

东方欲晓的专栏 901

# WPF ComboBox 控件详解与使用 —WPF 中的控件(7)--下拉框选项列表控件( ComboBox)

ComboBox`(下拉框选项列表)是 WPF 中最常用的选择类控件之一,它在有限空间内提供下拉选项列表,支持**单选、可编辑输入、数据绑定、自定义项外观**等核心能力,继承自 `System.Windows.Controls.Primitives.Selector`。 本文将从基础属性、核心事件、基础用法、数据绑定、自定义模板、高级定制到最佳实践,逐一带代码注解进行讲解。

yunmaowu0917的博客 142

从零搭建半导体设备上位机(五):三套 UI 库共存,HandyControl、MaterialDesign、Wu.Wpf 的样式基线

三套 UI 库共存:HandyControl、MaterialDesign、Wu.Wpf 的样式基线 这是「从零搭建半导体设备上位机」系列第5篇。一个 WPF 应用里同时装了 HandyControl、MaterialDesignThemes、Wu.Wpf 三套控件库。这篇讲它们为什么会打架、打架的具体机制是什么,以及怎么建立一套"谁也别想偷偷改我外观"的样式基线。 一个下拉框,白底白字 界面做完

samble的专栏 453
上一篇: 基于BREW平台的松耦合设计III-可移植、可复用软件的设计原则
下一篇: 基于BREW平台松耦合设计V-USBApp的设计和权衡
nicefuture
博客等级 码龄23年 75粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值