具有内置所有者描述支持的控件
Windows 窗体中的所有者描述(也称为自定义绘制)是一项用于更改某些控件的视觉外观的技术。
通常,Windows 使用 BackColor 等属性设置来确定控件的外观,从而自动处理控件的绘制。 使用所有者描述,您可以接管绘制进程,更改无法使用属性更改的外观元素。 例如,许多控件都允许设置文本的显示颜色,但都仅限于单一颜色。 使用所有者描述可以实现类似以下效果:将部分文字显示为黑色,将另一部分文字显示为红色。
实际上,所有者描述类似于在窗体上绘制图形。 例如,可以在窗体的 Paint 事件处理程序中使用图形方法来模拟 ListBox 控件,但是您必须编写自己的代码来处理所有的用户交互。 使用所有者描述,控件可以使用您的代码来绘制其内容,但仍保留其所有的内部功能。 您可以使用图形方法来绘制控件中的每个项,也可以对每个项的某些方面进行自定义,而对于每个项的其他方面使用默认外观。
Windows 窗体控件中的所有者描述
若要在支持所有者描述的控件中执行该功能,通常需要设置一个属性并处理一个或多个事件。
支持所有者描述的大多数控件都具有 OwnerDraw 或 DrawMode 属性,该属性指示当该控件绘制控件本身时该控件是否引发与其绘制相关的事件。
不具有 OwnerDraw 或 DrawMode 属性的控件包含 DataGridView 控件(提供自动发生的绘制事件)和 ToolStrip 控件(使用具有与自己的绘制相关事件的外部呈现类进行绘制)。
有许多不同类型的绘制事件,但通常发生的典型绘制事件是在控件中绘制单个项。 事件处理程序接收一个 EventArgs 对象,该对象包含与要绘制的项以及可用于绘制该项的工具有关的信息。 例如,此对象通常包含项在其父集合中的索引号、一个指示项的显示边界的 Rectangle 以及一个用于调用绘制方法的 Graphics 对象。 对于某些事件,EventArgs 对象可以提供有关项和方法的附加信息,默认情况下,您可以调用这些方法来绘制项的某些方面,例如背景或焦点框。
若要创建包含所有者描述的自定义内容的可重用控件,请创建一个从支持所有者描述的控件类派生的新类。 不需要对绘制事件进行处理,只需在新类中包含使用者描述代码,并重写相应的 On事件名称 方法即可。 在这种情况下,请确保调用 On事件名称 基类方法,以便该控件的用户可以处理所有者描述事件并提供其他自定义项。
以下 Windows 窗体控件在所有版本的 .NET Framework 中都支持所有者描述:
MenuItem(由 MainMenu 和 ContextMenu 使用)
以下控件仅在 .NET Framework 2.0 版中支持所有者描述:
以下控件是 .NET Framework 2.0 版中新增的支持所有者描述的控件:
以下部分提供了上述每个控件的其他详细信息。
ListBox 和 ComboBox 控件
ListBox 和 ComboBox 控件允许您绘制控件中的每个项,这些项可以采用相同的大小,也可以采用不同的大小。
提示
虽然 CheckedListBox 控件是从 ListBox 控件派生的,但它不支持所有者描述。
若要以相同的大小绘制每个项,请将 DrawMode 属性设置为 OwnerDrawFixed,并处理 DrawItem 事件。
若要使用不同的大小绘制每个项,请将 DrawMode 属性设置为 OwnerDrawVariable,然后处理 MeasureItem 和 DrawItem 事件。 使用 MeasureItem 事件可以在发生某项的 DrawItem 事件之前指定该项的大小。
有关更多信息(包括代码示例),请参见下列主题:
MenuItem 组件
MenuItem 组件表示 MainMenu 或 ContextMenu 组件中的单个菜单项。
若要绘制 MenuItem,请将其 OwnerDraw 属性设置为 true,然后处理其 DrawItem 事件。 若要在发生 DrawItem 事件之前自定义菜单项的大小,请处理该项的 MeasureItem 事件。
有关更多信息(包括代码示例),请参见下列参考主题:
TabControl 控件
TabControl 控件允许您绘制控件中的每个选项卡。 所有者描述只影响选项卡;不会影响 TabPage 的内容。
若要在 TabControl 中绘制每个选项卡,请将 DrawMode 属性设置为 OwnerDrawFixed,然后处理 DrawItem 事件。 如果选项卡在控件中可见,则对于每个选项卡,此事件只发生一次。
有关更多信息(包括代码示例),请参见下列参考主题:
ToolTip 组件
ToolTip 组件允许您在显示工具提示时绘制整个工具提示。
若要绘制 ToolTip,请将其 OwnerDraw 属性设置为 true,然后处理其 Draw 事件。 若要在发生 Draw 事件之前自定义 ToolTip 的大小,请处理 Popup 事件,并在事件处理程序中设置 ToolTipSize 属性。
有关更多信息(包括代码示例),请参见下列参考主题:
ListView 控件
ListView 控件允许您在该控件中绘制各个项、子项和列标题。
若要在该控件中启用所有者描述,请将 OwnerDraw 属性设置为 true。
若要在该控件中绘制每个项,请处理 DrawItem 事件。
若要在 View 属性设置为 Details 的情况下在控件中绘制每个子项或列标题,请处理 DrawSubItem 和 DrawColumnHeader 事件。
有关更多信息(包括代码示例),请参见下列参考主题:
TreeView 控件
TreeView 控件允许您在控件中绘制各个节点。
若要仅绘制每个节点中显示的文本,请将 DrawMode 属性设置为 OwnerDrawText,然后处理 DrawNode 事件以绘制该文本。
若要绘制每个节点的所有元素,请将 DrawMode 属性设置为 OwnerDrawAll,然后处理 DrawNode 事件以绘制所需的所有元素,例如文本、图标、复选框、加号和减号以及连接节点的线条。
有关更多信息(包括代码示例),请参见下列参考主题:
DataGridView 控件
DataGridView 控件允许您在控件中绘制各个单元格和行。
若要绘制各个单元格,请处理 CellPainting 事件。
若要绘制各个行或行的元素,请处理 RowPrePaint 和 RowPostPaint 事件之一,或同时处理这两个事件。 RowPrePaint 事件发生在绘制行中的单元格之前,RowPostPaint 事件发生在绘制单元格之后。 可以处理这两个事件和 CellPainting 事件以分别绘制行背景、各个单元格和行前景,也可以根据需要进行具体的自定义,而对于行的其他元素使用默认显示。
有关更多信息(包括代码示例),请参见下列主题:
ToolStrip 控件
ToolStrip 及其派生控件可以对控件外观的任意方面进行自定义。
若要为 ToolStrip 控件提供自定义呈现,请将 ToolStrip、ToolStripManager、ToolStripPanel 或 ToolStripContentPanel 的 Renderer 属性设置为 ToolStripRenderer 对象,然后处理 ToolStripRenderer 类所提供的众多绘制事件中的一个或多个事件。 此外,也可以将 Renderer 属性设置为您自己的类的一个实例,该类是从实现或重写特定 On事件名称 方法的 ToolStripRenderer、ToolStripProfessionalRenderer 或 ToolStripSystemRenderer 派生的。
有关更多信息(包括代码示例),请参见下列主题: