惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google Online Security Blog
Google Online Security Blog
P
Proofpoint News Feed
Martin Fowler
Martin Fowler
D
DataBreaches.Net
V
Visual Studio Blog
M
MIT News - Artificial intelligence
C
Check Point Blog
The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
F
Full Disclosure
MongoDB | Blog
MongoDB | Blog
GbyAI
GbyAI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
I
InfoQ
aimingoo的专栏
aimingoo的专栏
L
LangChain Blog
Recorded Future
Recorded Future
B
Blog RSS Feed
Y
Y Combinator Blog
Stack Overflow Blog
Stack Overflow Blog
博客园 - 司徒正美
Forbes - Security
Forbes - Security
美团技术团队
Google DeepMind News
Google DeepMind News
H
Help Net Security
L
LINUX DO - 最新话题
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
W
WeLiveSecurity
MyScale Blog
MyScale Blog
O
OpenAI News
P
Privacy & Cybersecurity Law Blog
Attack and Defense Labs
Attack and Defense Labs
N
Netflix TechBlog - Medium
T
Troy Hunt's Blog
月光博客
月光博客
Recent Commits to openclaw:main
Recent Commits to openclaw:main
B
Blog
V
V2EX
WordPress大学
WordPress大学
H
Heimdal Security Blog
U
Unit 42
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Simon Willison's Weblog
Simon Willison's Weblog
S
SegmentFault 最新的问题
SecWiki News
SecWiki News
D
Docker
Blog — PlanetScale
Blog — PlanetScale
S
Secure Thoughts

博客园 - yet

利用SQL2005的forxml以及反系列化去替代ORM? 怎样去获取文章简介 用自己的MVC框架 (小技巧)怎样有选择的去屏蔽验证控件。 高校软件杯作品:DreamChat[校园即时通] 梦凌NET期刊管理系统 一却都好像都在肢解着我 <远程教育系统>体系结构设计 协议分析[高校杯准备] 把.NET程序部署到没有安装.NET Framwork的机器上 项目打包时自定义安装属性,如数据库名等 自动安装SQL Server数据库 在制作打包程序的时候自动在用户计算机中还原SQL数据库 截系统热键 IP多播技术[为软件高校杯做准备] 自定义提供程序控件 实现支持断点续传多线程下载的 Http Web 客户端工具类() 身份证验证算法 C#编写QQ接口软件--QQ协议篇
自定义提供程序控件(续)
yet · 2005-07-20 · via 博客园 - yet

让我们增强这个简单的 TextBox 扩展程序,以便为每个 extendee 提供更好的支持。扩展程序现在将添加两个属性 — 背景色和前景色。
[ProvideProperty("SelectedBackColor", typeof(TextBox))]
[ProvideProperty("SelectedForeColor", typeof(TextBox))]
public class TextBoxExtender : Component, IExtenderProvider
{
   private Hashtable Extendees;

   public TextBoxExtender()
   {
       InitializeComponent();

       // Use a hashtable to track selected colors
       // for each extendee
       this.Extendees = new Hashtable();
   }

   •••
}

每个 extendee 控件都被分配给按如下方式构造的信息类:

public class TextBoxInfo
{
   public Color SelectedBackColor;
   public Color OldBackColor;
   public Color SelectedForeColor;
   public Color OldForeColor;
   public bool  EventsWired;
}

该类不但跟踪要使用的颜色,而且跟踪要恢复的颜色,并对 GotFocus 和 LostFocus 事件仅绑定一次,这是由 EventsWired 属性指示的。Get/Set 对的代码变得有点复杂。让我们先处理 Get 访问器:

public Color GetSelectedBackColor(Control control)
{
   // Retrieve related info
   TextBox t = (TextBox) control;
   TextBoxInfo info = (TextBoxInfo) Extendees[t];

   return info.SelectedBackColor; 
}

控件参数引用实际的 extendee 控件 — 在本例中为 TextBox。在获得了对基础控件的引用之后,还可以基于可访问的名称或任何其他属性筛出控件。将控件引用用作访问哈希表和检索相应 TextBoxInfo 结构的关键字。在此之后,返回要使用的背景色易如反掌。

谁正在哈希表中创建条目,以及何时创建?其中一个属性的 Set 访问器负责在哈希表中插入控件。如果类似的条目已经存在于哈希表中,将不会添加控件。下面显示了 SetSelectedBackColor 方法的源代码。
public void SetSelectedBackColor(Control control, Color
    selColor)
{
    TextBoxInfo info;
    TextBox t = (TextBox) control;
    if (!Extendees.ContainsKey(t))
        info = new TextBoxInfo();
    else
        info = (TextBoxInfo) Extendees[t];

    // Store the new value
    info.SelectedBackColor = selColor;

    // If not already done, wire events up
    if (!info.EventWired)
    {
        t.GotFocus += new EventHandler(TextBox_GotFocus);
        t.LostFocus += new EventHandler(TextBox_LostFocus);
        info.EventWired = true;
    }

    // Add to the table
    if (!Extendees.ContainsKey(t))
        Extendees[t] = info;
}

ToolTip 类被密封并且不能被继承,因此不能添加更多的功能(如气球样式)。在 Windows XP 和更新的操作系统中,ToolTip 窗口已被赋予 TTS_BALLOON 样式,以便在气球样式弹出窗口中显示标题。首先,从现有的 ToolTip 提供程序派生新扩展程序类并为气球样式添加支持,这看上去是相对简单的任务。您遇到的第一个问题就是 ToolTip 类是密封类,即它不再可继承。但是,通过使用聚合(而非继承),您可以设计自定义包装扩展程序,以便利用 ToolTip 类的基础功能。

其思路在于在扩展程序的构造函数中创建 ToolTip 类的新实例,并在新的 ToolTip 属性的 get 和 set 访问器中调用 GetToolTip 和 SetToolTip 方法。

[ProvideProperty("MyText", typeof(TextBox))]
public class MyToolTip : Component, IExtenderProvider
{
   private ToolTip _toolTip;
   public MyToolTip() 
   {
      toolTip = new ToolTip();
   }
   
}

MyToolTip 类嵌入 ToolTip 类的动态创建的实例作为其私有属性,并公开 MyText 扩展属性。此属性的实现通过针对初始 ToolTip 类实现文本属性来传递:

public string GetMyText(Control control)
{
   return _toolTip.GetToolTip(control); 
}

public void SetMyText(Control control, string caption)
{
   // TODO :: Enter your changes...

   _toolTip.SetToolTip(control, caption);
}
扩展 ToolTip 扩展程序

通过实现此代码,可以完成自己的自定义扩展程序,并使其在现有 ToolTip 组件的上方工作。扩展 ToolTip 的一个很好的理由是使用自定义的 ToolTip 控件。Windows 窗体 ToolTip 不支持气球和多行样式,只能通过自定义 ToolTip 扩展程序添加这些功能。不幸的是,在三个内置扩展程序中,您需要的扩展程序(即 ToolTip 组件)是密封的,并且不能被继承。因此,您必须采用基于控件聚合的方法。

然而,在实现完全自定义 Windows 窗体 ToolTip 的过程中,主要的障碍却不在这里。ToolTip 控件从 Component(而非 Control)继承。对于哪种方式更好这一问题存在一些争论。如果您从 Component 继承某个类,该类的行为方式类似于控件栏组件,这对于扩展程序非常适合。如果从 Control 派生该类,结果组件无法放在 IDE 栏区域中。然而,它将从基类继承 Handle 属性。

Handle 属性表示基础 Win32 控件的 HWND句柄。由于 Windows 窗体在很大程度上基于 Win32 控件,因此当 Control 对象被实例化时,Windows 窗体会创建一个窗口。要自定义控件的外观和行为,您需要采用 Win32 样式和消息。如果您不能访问基础窗口句柄,则如何设置它们?

ToolTip 托管控件确实有一个被定义为 IntPtr 成员的 Handle 属性。回忆一下,IntPtr 是用来映射 Win32 句柄(如 HWND、HGLOBAL 或 HKEY)的 .NET Framework 类型。困难在于如下事实,ToolTip 的句柄属性被声明为私有属性,所以会因其保护级别而变得不可访问。ToolTip 类可以使用聚合功能进一步扩展,但是,能够实际添加的扩展仅限于在不知道基础 ToolTip 窗口的 HWND 的情况下所能实现的任何事情。

以上源代码下载地址: CuttingEdge0311.exe (139KB)