IssueVision的List控件源码分析

==============================================
Me.SetStyle 为什么没有智能感知?
==============================================
DataRowView:当数据显示(例如显示在DataGrid 控件中)时,每一行只显示一种版本。所显示的行是 DataRowView。
DataRowView 可以具有以下四个不同的版本状态之一:Default、Original、Current 和 Proposed。
在针对 DataRow 调用 BeginEdit 之后,任何已编辑的值变成 Proposed 值。在调用 CancelEdit 或 EndEdit 之前,行具有 Original 和 Proposed 版本。如果调用 CancelEdit,则建议版本将被丢弃,该值还原到原始值。如果调用 EndEdit,则 DataRowView 不再具有 Proposed 版本;相反,建议值将变成当前值。默认值只在那些列具有已定义的默认值的行上可用。
==============================================
<Category("Data"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
==============================================
当序列化程序保持设计模式文档的可持续状态时,它通常会向组件的初始化方法中添加代码,以便保持已在设计时设置的属性值。如果尚未设置指示其他行为的特性,大多数基类型都会默认出现此情况。
DesignerSerializationVisibilityAttribute 允许您指示属性值是否为 Visible,是否应在初始化代码中保持,Hidden,是否不应在初始化代码中保持,是否由 Content 组成,它应具有为分配到该属性的对象的每个公共属性(而非隐藏属性)生成的初始化代码。
没有 DesignerSerializationVisibilityAttribute 的成员将被视为具有值为 Visible 的 DesignerSerializationVisibilityAttribute。如果可能,序列化程序会将标记为 Visible 的属性值序列化为该类型。要为特定类型或属性指定自定义序列化,请使用 DesignerSerializerAttribute。
==============================================
Control.SuspendLayout 方法
控件的布局逻辑被挂起,直到调用 ResumeLayout 方法为止。
当调整控件的多个属性时,将先后使用 SuspendLayout 和 ResumeLayout 方法取消多个 Layout 事件。例如,通常先调用 SuspendLayout 方法,然后设置控件的 Size、Location、Anchor 或 Dock 属性,最后调用 ResumeLayout 方法以使更改生效。
==============================================
DirectCast 关键字引入类型转换操作。该关键字的使用方法与 CType 关键字相同,如下列所示:

Dim Q As Object = 2.37   ' Requires Option Strict to be Off.
Dim I As Integer = CType(Q, Integer)   ' Succeeds.
Dim J As Integer = DirectCast(Q, Integer)   ' Fails.
这两个关键字都将要转换的表达式作为第一个参数,而将要转换成的类型作为第二个参数。如果未定义表达式的数据类型与第二个参数所指定的数据类型之间的转换,那么这两种转换都会失败。

这两个关键字之间的差别在于:只要定义了表达式与类型之间的有效转换,CType 即可成功,而 DirectCast 则要求对象变量的运行时类型与指定的类型相同。不过,如果表达式的指定类型和运行时类型相同,则 DirectCast 的运行时性能比 CType 的运行时性能好。
===============================================
控件为什么反向添加呢?
            '反向添加
            For i As Integer = al.Count To 0 Step -1
                Controls.Add(DirectCast(al(i), Control))
            Next
===============================================
设置双缓冲与Graphic释放关系,如果做了双缓冲设置不要立刻释放Graphic否则图形没有绘制完成会产生错误。



上边记录的主要是基于代码的学习笔记,后来晚上仔细从结构上进行了一点分析,真是觉得这个控件设计的很巧妙,下边从结构上简单说说。

在整个List上实际上由不同的SectionControl和Spliter控件组成,为什么要用Spliter呢,主要是为了控制每个SectionControl的缩放,这个方法节约了很大的工作量。Spliter的Enabled属性是False的,这样鼠标放上去就没有效果了,如果不看代码这块是很难理解的。

每个SectionControl的处理也很巧妙,首先是在界面上安排了一个PictureBox,用来显示那个“+”“-”的图标,其次,通过画笔来绘制Header和每一个Item,处理的方法很简单。

最关键的是事件的触发过程,SectionControl的OnPaint是基础,通过它向上层控件发送绘制消息,从而带动整个控件的绘制消息驱动。

在上游的图标控制上,实际上也是通过重写绘图来实现的。

现在看整个List实际上是由不同的部分组成,借助绘制事件消息的传递来带动整个界面的绘制,通过重写部分特定函数来扩展List的功能。

当然上边说的还没有涉及到数据处理那块,因为还没有看呢,这里作个笔记以免以后忘掉了。

看代码+写代码+MSDN+GOOGle=最好的学习方式

你可能感兴趣的:(设计模式,数据结构,工作,Google,J#)