本文档提供了关于创建自定义编辑器的总说明,这些自定义编辑器可以独立使用,或者作为内置编辑器 (例如在 XtraGrid 中)。 可以参阅 编辑器的类结构 章节,该章节描述了 XtraEditors 库中所使用的并且自定义编辑器必须遵循的对象模型。
总说明
- 创建一个实现了特定行为的自定义编辑器类
如果需要为编辑器实现全新的功能,那么可以继承于 XtraEditors 库中所有编辑器的始祖 BaseEdit 类。 如果所创建的编辑器与某个现有的编辑器有共同之处,那么可以继承于适当的编辑器。 关于包含在此库中的编辑器的信息,请参阅 编辑器的层次结构 主题。
- 创建一个存储编辑器特定属性的自定义 repository 项类
在 XtraEditors 库中的每个编辑器都有一个被称为“repository 项”的关联对象,并且存储了编辑器的特定设置和事件处理程序。 例如,DateEdit 控件的设置通过 RepositoryItemDateEdit 类被封装, 而 ImageComboBoxEdit 编辑器的设置通过 RepositoryItemImageComboBox 类提供,等等。 所有 repository 项都派生于 RepositoryItem 基类。
对每个自定义编辑器,都必须创建一个自定义的 repository 项类。 该类至少应该重写 EditorTypeName 属性。 另外,自定义的 repository 项可以推出新设置、新事件,或者重定义默认设置的处理。 如果编辑器派生于 BaseEdit 类,那么新 repository 项应该派生于 RepositoryItem 类来创建。 例如,如果创建 DateEdit 的子类,那么新 repository 项应该继承于 RepositoryItemDateEdit 类,等等。编辑器的 Properties 属性必须被重写,使得它能返回某个相应的 repository 项。
- 注册编辑器和 repository 项。
每个编辑器都必须被注册到一个内部注册集合中,以便于此编辑器可以通过 PersistentRepository 组件或任一容器控件 (XtraGrid、XtraBars 等) 进行访问。 注册代码必须放置在 repository 项类的某个静态方法中。
关于这一点的更多细节在下面给出。
通常把实现自定义编辑器的代码放置在一个独立库中。 例如,在编译此库之后,可以使用 项目->添加引用 菜单命令把它添加到应用程序项目中。 然后,此自定义编辑器可以通过 PersistentRepository 的设计器或任一容器控件的设计器进行访问。
注意 |
---|
仅当第一次打开设计器时,设计器才会搜索附属于应用程序的自定义编辑器。 因此,如果打开了设计器,然后把引用添加到编辑器库,那么在下次打开设计器之时,此编辑器也不会被显示。 在那种情况下,需要重新加载应用程序来查看已经被添加的自定义编辑器。 |
自定义编辑器类
如果为编辑器新建了一个 repository 项类,那么必须重写此编辑器的 Properties 属性。 仅应该重写 get 方法,且此方法必须只返回基础类的 Properties、其对象类型转换为相应的 repository 项类型。 注意,Properties 属性值不需要人工创建。 根据注册信息,一个相应的对象会被自动创建。
自定义编辑器也必须提供一个调用注册代码的静态构造函数。 请参阅下面的示例。
自定义 Repository 项类
Repository 项类必须包含一个调用了注册代码的静态构造函数。 注册代码必须放置在一个独立的静态方法中。
如果需要为 repository 项添加新属性或新事件,那么需要重写 Assign 方法。 必须把作为此方法的参数传递的 repository 项的设置,复制到当前的项。
注册
如上所述,自定义编辑器和 repository 项都必须包含调用注册方法的静态构造函数。
对 repository 项类,必须添加下列属性: [UserRepositoryItem("RegisterCustomEdit")],其中“RegisterCustomEdit”是静态的注册方法的名称。要提供关于自定义编辑器的注册信息,必须创建一个 DevExpress.XtraEditors.Registrator.EditorClassInfo 对象。 可以使用该类的构造函数的重载,来提供注册信息:
C# | 复制代码 |
---|---|
public EditorClassInfo( string name, // Specifies the editor's name. Type editorType, // Specifies the type of the editor class. Type repositoryType, // Specifies the type of the custom repository item class. Type viewInfoType, // Specifies the type of the editor's ViewInfo class. BaseEditPainter painter,// An instance of the editor's Painter class. bool designTimeVisible, // Specifies whether the custom editor // will be visible at design time within container controls // (for instance, when creating an in-place editor // within the XtraGrid or XtraBars). Image image, // Specifies the image that will be displayed along // with the editor's name within container controls. Type accessibleType // Specifies the type of the object // that provides accessibility information. ); |
通常,需要把 viewInfoType 和 accessibleType 参数设置为与自定义编辑器的祖先相应的 ViewInfo 和 AccessibilityInformation 类型。 对于 painter 参数,需要指定相应的 Painter 类的某个实例。 下表说明了这些与 XtraEditors 库中特定的标准编辑器相应的类:
编辑器 | ViewInfo 类 (DevExpress.XtraEditors.ViewInfo 命名空间) | Painter 类 (DevExpress.XtraEditors.Drawing 命名空间) | AccessibilityInformation 类 (DevExpress.Accessibility 命名空间) |
---|---|---|---|
BaseEdit | BaseEditViewInfo | BaseEditPainter | BaseEditAccessible |
ButtonEdit | ButtonEditViewInfo | ButtonEditPainter | ButtonEditAccessible |
CalcEdit | CalcEditViewInfo | ButtonEditPainter | PopupEditAccessible |
CheckedComboBoxEdit | PopupContainerEditViewInfo | ButtonEditPainter | PopupEditAccessible |
CheckEdit | CheckEditViewInfo | CheckEditPainter | CheckEditAccessible |
ColorEdit | ColorEditViewInfo | ColorEditPainter | PopupEditAccessible |
ComboBoxEdit | ComboBoxViewInfo | ButtonEditPainter | PopupEditAccessible |
DateEdit | DateEditViewInfo | ButtonEditPainter | PopupEditAccessible |
FontEdit | ComboBoxViewInfo | ButtonEditPainter | PopupEditAccessible |
GridLookUpEdit | GridLookUpEditBaseViewInfo | ButtonEditPainter | PopupEditAccessible |
HyperLinkEdit | HyperLinkEditViewInfo | HyperLinkEditPainter | ButtonEditAccessible |
ImageComboBoxEdit | ImageComboBoxEditViewInfo | ImageComboBoxEditPainter | PopupEditAccessible |
ImageEdit | ImageEditViewInfo | BlobBaseEditPainter | PopupEditAccessible |
LookUpEdit | LookUpEditViewInfo | ButtonEditPainter | PopupEditAccessible |
MarqueeProgressBarControl | MarqueeProgressBarViewInfo | ProgressBarPainter | ProgressBarAccessible |
MemoEdit | MemoEditViewInfo | MemoEditPainter | TextEditAccessible |
MemoExEdit | MemoExEditViewInfo | BlobBaseEditPainter | PopupEditAccessible |
MRUEdit | MRUEditViewInfo | ButtonEditPainter | PopupEditAccessible |
PictureEdit | PictureEditViewInfo | PictureEditPainter | BaseEditAccessible |
PopupContainerEdit | PopupContainerEditViewInfo | ButtonEditPainter | PopupEditAccessible |
ProgressBarControl | ProgressBarViewInfo | ProgressBarPainter | ProgressBarAccessible |
RadioGroup | RadioGroupViewInfo | RadioGroupPainter | RadioGroupAccessible |
RangeTrackBarControl | RangeTrackBarViewInfo | RangeTrackBarPainter | RangeTrackBarAccessible |
SpinEdit | BaseSpinEditViewInfo | ButtonEditPainter | BaseSpinEditAccessible |
TextEdit | TextEditViewInfo | TextEditPainter | TextEditAccessible |
TimeEdit | BaseSpinEditViewInfo | ButtonEditPainter | BaseSpinEditAccessible |
TrackBarControl | TrackBarViewInfo | TrackBarPainter | TrackBarAccessible |
ZoomTrackBarControl | ZoomTrackBarViewInfo | ZoomTrackBarPainter | ZoomTrackBarAccessible |
在创建 EditorClassInfo 之后,需要把它添加到 DevExpress.XtraEditors.Registrator.EditorRegistrationInfo.Default.Editors 静态集合中。 请参阅下面的创建一个自定义编辑器的示例代码。
示例
让我们考虑一个创建自定义编辑器 (CustomEdit) 的简单示例,来呈现 TextEdit 类的子类。 新的 repository 项类是 RepositoryItemCustomEdit。 为了达到举例说明的目的,引入了一个新属性 (UseDefaultMode)。
C# | 复制代码 |
---|---|
using System.Drawing; using System.Reflection; using System.ComponentModel; using System.Windows.Forms; using DevExpress.XtraEditors; using DevExpress.XtraEditors.Repository; using DevExpress.XtraEditors.Registrator; using DevExpress.XtraEditors.Drawing; using DevExpress.XtraEditors.ViewInfo; namespace DevExpress.CustomEditors { //The attribute that points to the registration method [UserRepositoryItem("RegisterCustomEdit")] public class RepositoryItemCustomEdit : RepositoryItemTextEdit { //The static constructor which calls the registration method static RepositoryItemCustomEdit() { RegisterCustomEdit(); } //Initialize new properties public RepositoryItemCustomEdit() { useDefaultMode = true; } //The unique name for the custom editor public const string CustomEditName = "CustomEdit"; //Return the unique name public override string EditorTypeName { get { return CustomEditName; } } //Register the editor public static void RegisterCustomEdit() { //Icon representing the editor within a container editor's Designer Image img = null; try { img = (Bitmap)Bitmap.FromStream(Assembly.GetExecutingAssembly(). GetManifestResourceStream("DevExpress.CustomEditors.CustomEdit.bmp")); } catch { } EditorRegistrationInfo.Default.Editors.Add(new EditorClassInfo(CustomEditName, typeof(CustomEdit), typeof(RepositoryItemCustomEdit), typeof(TextEditViewInfo), new TextEditPainter(), true, img)); } //A custom property private bool useDefaultMode; public bool UseDefaultMode { get { return useDefaultMode; } set { if(useDefaultMode != value) { useDefaultMode = value; OnPropertiesChanged(); } } } //Override the Assign method public override void Assign(RepositoryItem item) { BeginUpdate(); try { base.Assign(item); RepositoryItemCustomEdit source = item as RepositoryItemCustomEdit; if(source == null) return; useDefaultMode = source.UseDefaultMode; } finally { EndUpdate(); } } } public class CustomEdit : TextEdit { //The static constructor which calls the registration method static CustomEdit() { RepositoryItemCustomEdit.RegisterCustomEdit(); } //Initialize the new instance public CustomEdit() { //... } //Return the unique name public override string EditorTypeName { get { return RepositoryItemCustomEdit.CustomEditName; } } //Override the Properties property //Simply type-cast the object to the custom repository item type [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public new RepositoryItemCustomEdit Properties { get { return base.Properties as RepositoryItemCustomEdit; } } } } |
Visual Basic | 复制代码 |
---|---|
Imports System.Reflection Imports System.Drawing Imports System.ComponentModel Imports System.Windows.Forms Imports DevExpress.XtraEditors Imports DevExpress.XtraEditors.Repository Imports DevExpress.XtraEditors.Registrator Imports DevExpress.XtraEditors.Drawing Imports DevExpress.XtraEditors.ViewInfo 'The attribute that points to the registration method <UserRepositoryItem("RegisterCustomEdit")> _ Public Class RepositoryItemCustomEdit Inherits RepositoryItemTextEdit 'The static constructor which calls the registration method Shared Sub New() RegisterCustomEdit() End Sub 'Initialize new properties Public Sub New() _useDefaultMode = True End Sub 'The unique name for the custom editor Public Const CustomEditName As String = "CustomEdit" 'Return the unique name Public Overrides ReadOnly Property EditorTypeName() As String Get Return CustomEditName End Get End Property 'Register the editor Public Shared Sub RegisterCustomEdit() 'Icon representing the editor within a container editor's Designer Dim img As Image = Nothing Try img = Bitmap.FromStream( _ Assembly.GetExecutingAssembly().GetManifestResourceStream( _ "DevExpress.CustomEditors.CustomEdit.bmp")) Catch End Try EditorRegistrationInfo.Default.Editors.Add(New EditorClassInfo(CustomEditName, _ GetType(CustomEdit), GetType(RepositoryItemCustomEdit), _ GetType(TextEditViewInfo), New TextEditPainter, True, img)) End Sub 'A custom property Private _useDefaultMode As Boolean Public Property UseDefaultMode() As Boolean Get Return _useDefaultMode End Get Set(ByVal Value As Boolean) If (Not _useDefaultMode = Value) Then _useDefaultMode = Value OnPropertiesChanged() End If End Set End Property 'Override the Assign method Public Overrides Sub Assign(ByVal item As RepositoryItem) BeginUpdate() Try MyBase.Assign(item) Dim source As RepositoryItemCustomEdit = CType(item, RepositoryItemCustomEdit) If source Is Nothing Then Return _useDefaultMode = source.UseDefaultMode Finally EndUpdate() End Try End Sub End Class Public Class CustomEdit Inherits TextEdit 'The static constructor which calls the registration method Shared Sub New() RepositoryItemCustomEdit.RegisterCustomEdit() End Sub 'Initialize the new instance Public Sub New() '... End Sub 'Return the unique name Public Overrides ReadOnly Property EditorTypeName() As String Get Return RepositoryItemCustomEdit.CustomEditName End Get End Property 'Override the Properties property 'Simply type-cast the object to the custom repository item type <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _ Public Shadows ReadOnly Property Properties() As RepositoryItemCustomEdit Get Return CType(MyBase.Properties, RepositoryItemCustomEdit) End Get End Property End Class |
上述注册方法使自定义图像 (已经被作为资源添加到项目中) 与编辑器相关联。 在设计时刻,该图像将被显示在 PersistentRepository 的或容器编辑器的设计器中。
要把图像作为资源添加到项目中,则执行下列操作:
- 在 解决方案资源管理器 中使用鼠标右键单击项目,并选中 添加 -> 添加现有项 选项。 加载需要与编辑器相关联的自定义图像。
- 在 解决方案资源管理器 中选中此图像。 它的名称必须与编辑器的名称相匹配。 如果不匹配,则 (例如) 通过按下 F2 键来重命名它。
- 在 解决方案资源管理器 中使用鼠标右键单击此图像,并选中 属性 选项。 在 属性 窗口中,把 生成操作 项设置为 嵌入的资源。
要获得关于创建自定义编辑器的其他示例,请参阅与安装一起提供的 MyControls1 演示。 在默认情况下,C# 和 VB 版本的示例分别被安装在 Program Files\Developer Express .NET vX.Y\Demos\XtraEditors\CS\MyControls1\ 和 Program Files\Developer Express .NET vX.Y\Demos\XtraEditors\VB\MyControls1\ 文件夹中。