`
zhmocean
  • 浏览: 202654 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

控件间关联,Notification不能忘

阅读更多
 来龙去脉
最近在编写一些简单控件时,用到了控件间的关联,即一个控件属性中组合了另一个控件的实例(类似于TDataSource的DataSet属性),控件编写和运行一切顺利,但随后的设计期操作却让人不知所措。
设计期,在窗体拖放两个控件,并将其关联,如A的一个属性是B,由于delphi设计期拥有强大的即时处理能力,关联好之后,两个控件的设置立即生效。
但是,此时如果将B从窗体删除,让人不快的事情发生了,一个红叉叉对话框告诉我们,“rtl10.bpl”之类的核心出现异常,点击OK按钮,界面开始混乱,对话框不断,只能用任务管理器强行结束,貌似是致命性错误。
再次打开delphi,上述问题依旧存在,而且排除了delphi的BUG问题(已升级到最新的hotfix),因为delphi自带的关联控件(比如TDataSource和TDataSet关联)不会出现错误,那么就是我的控件在设计期出现了错误。
由于对设计期delphi的控件管理不了解,只好使用Ctrl跟踪了TfrxDBDataset的DataSet关联(TDataSource使用了特殊的关联通知方式,并结合了StateChange事件,不具通用性),发现在TfrxDBDataset中存在这样一个函数:
 
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure TfrxDBDataset.Notification(AComponent: TComponent; Operation: TOperation);
begin
 inherited;
 if Operation = opRemove then
    if AComponent = FDataSource then
      DataSource := nil
    else if AComponent = FDataSet then
      DataSet := nil
end;
 
很明显Notification是override的基类的函数,它是TComponet类型控件互动通知模式的一部分,控件互动通知模式可以使关联的控件在创建或销毁时,通过该函数通知被关联的控件。在此前编写的控件,由于没有在关联控件销毁时即时将被关联控件相关属性设为空,造成了指针失效错误,而由于是在设计期产生的,因而引发了delphi IDE的致命错误。因此,要解决上述问题,只需要重载Notification函数,在接收到opRemove(控件被移除)操作时将相关属性设为空即可。
修改完毕,再次编译、安装控件,问题解决。
经验总结
1、    VCL内部使用了诸多优秀的设计模式,并发挥了强大的作用。理清VCL的设计脉络有助于我们尽快的找到设计的不足和解决方法。
2、    VCL绝大部分都具有源代码,遇到问题时勤于跟踪现有代码,会在解决问题的基础上提高我们的设计水平。
3、    设计中出现错误时,可使用替换法缩小问题范围,用现有的正常代码与问题代码做比较,找出问题所在。
 
分享到:
评论

相关推荐

    常用控件实验

    10. **控件数组(Control Arrays)**:对于数量不固定的控件,如动态创建的一系列按钮,可以使用控件数组来管理,方便统一处理。 通过这个“常用控件实验”,开发者不仅能熟悉各个控件的功能和使用方式,还能掌握如何...

    Notification用法

    在Android开发中,Notification是一种非常重要的组件,它用于在用户不与应用交互时提供系统级别的消息提醒。通过Notification,开发者可以向用户展示重要的信息,如新邮件、未接来电、天气更新等。本教程将深入讲解...

    android NotificationDemo

    在Android开发中,Notification是应用与用户交互的重要方式,它能够在状态栏中显示信息,即使应用在后台运行也能提醒用户。本示例"android NotificationDemo"着重于如何自定义View来实现更个性化的通知功能。 首先...

    VC6.0中ActiveX控件 Media Player 中用CWMPPlayer4类做视频播放器

    为 ActiveX 控件关联一个 CWMPPlayer4 类型的变量 m_player。 在关联 CWMPPlayer4 类型的变量 m_player 后,需要为按钮控件添加消息处理响应函数,以实现文件的打开和播放。下面是实现文件打开和播放的代码: void...

    IOCP控件_Delphi(含DEMO)

    1. **控件源码**:展示了如何在Delphi中实现IOCP相关的类和组件,包括创建完成端口、关联句柄、提交I/O请求以及处理完成的I/O操作。 2. **服务器端示例**:演示了如何使用IOCP控件建立一个高性能的服务器,处理来自...

    Android Notification Demo

    在Android开发中,通知(Notification)是应用与用户交互的重要方式之一,特别是在后台运行时,它能向用户提供信息,而不必打开应用。本教程通过"Android Notification Demo"将深入探讨如何创建和定制各种类型的...

    Android源码——多种android控件的Demo_new_40.zip

    通过深入研究这个压缩包中的源码,开发者不仅能学习到Android控件的基本用法,还能了解其背后的设计思想和最佳实践。实践中,不断试验和调试,将理论知识转化为实际技能,是成为一名优秀Android开发者的关键步骤。...

    Android使用Notification实现普通通知栏(一)

    使用`NotificationCompat.Builder`的`setContentIntent()`方法,可以将这个`PendingIntent`与Notification关联起来,使得点击通知时能启动指定的Activity。 以下是一个简单的示例,展示了如何创建一个包含点击行为...

    NotificationDemo:有关Android中通知的教程示例

    在Android开发中,通知(Notifications)是用户界面中不可或缺的一部分,它们用来在状态栏中向用户传达重要信息,即使用户不在应用中也能接收到。"NotificationDemo"是一个专门用于教授如何在Android应用中实现和...

    Android 多种android控件的Demo-IT计算机-毕业设计.zip

    在Android开发中,掌握各种控件的使用是至关重要的,因为它们构成了用户界面的基础,直接影响到应用程序的用户体验。本项目“Android多种android控件的Demo”是一个毕业设计学习资源,旨在帮助开发者熟悉并掌握...

    控件相关DEV

    ### 控件相关DEV知识点解析 #### 一、DevExpress MVVM Framework 概览 DevExpress MVVM Framework 是一个功能强大的工具包,旨在简化WPF应用程序的开发流程。它通过一系列的行为(Behaviors)、转换器(Converters...

    PopupNotificationExtender

    - **触发器关联**:可以与任何服务器控件关联,当触发器被操作时显示通知。 4. **使用方法** 在ASP.NET页面中,首先需要引用AjaxControlToolkit库。然后,在.aspx页面的标签内添加。接着,添加...

    JavaFX表单验证

    在JavaFX中,我们可以利用内置的验证机制来检查用户在TextField和ComboBox等控件中输入的信息,确保它们满足特定的格式要求。 对于TextField,常见的验证场景包括但不限于: 1. 非空验证:确保用户至少输入了一个...

    VC界面类编程

    例如,减少不必要的重绘,使用控件的更新区域(UpdateRect),以及合理使用异步通知(Asynchronous Notification)来提高响应速度。 通过熟练掌握上述知识点,开发者能够构建出高效、美观的VC界面应用,提供优质的...

    UWP程序开发200例

    2. **页面导航**:了解如何在UWP应用中实现页面间的导航,包括使用`Frame`控件和`Page`类,以及掌握`NavigationCacheMode`等导航特性。 3. **数据绑定**:掌握数据绑定的基本原理,包括单向、双向绑定,以及如何...

    VC++6.0_MFC基于对话框简单计算器设计

    我们将使用快捷键CTRL+W打开MFC ClassWizard,并在Member Variables中添加三个double型关联变量m_EDIT1_NUM、m_EDIT2_NUM和m_EDIT3_NUM。 接下来,我们将添加20个按钮控件,用于实现运算操作。这些按钮控件将具有...

    安卓通知栏例子

    开发者可以通过`createNotificationChannel()`方法创建频道,并用`NotificationChannel.ID`将其关联到通知。例如: ```java NotificationChannel channel = new NotificationChannel("my_channel_id", "My Channel...

    ios多tab demo

    5. ** outlets和actions**: 在Storyboards中,outlets用于将UI控件与代码中的属性关联,而actions则用来绑定控件的事件处理方法。开发者可以通过outlets获取UI的状态,通过actions响应用户的操作。 6. **Segues**: ...

    Android入门

    - 上下文菜单:与特定控件关联的菜单。 25. **ActionBar详解** - 提供了一个标准的标题栏。 - 可以包含标题、按钮等元素。 - 支持下拉导航、操作视窗等功能。 26. **viewPager详解** - 实现页面滑动效果。 -...

Global site tag (gtag.js) - Google Analytics