返回首页

简介
这是现成的使用它可以帮助您创建你自己的设计时间控件属性编辑在下拉一个ModalForm窗口或在Visual Studio IDE中的设计模式UITypeEditors的代码。要使用它,从它继承的类,将该属性添加到您的控制项属性(IES):

<Editor(GetType(MyPropertyEditor), 

        GetType(System.Drawing.Design.UITypeEditor))>

有些样品在下面的图像所示:
{S0}{S1}图1)使用一个ListBox编辑器图2)使用TreeView编辑
{S2}图3)使用UserControl的编辑器{S3}图4)使用模态窗体编辑器"PropertyEditorBase"类
这是一个抽象(MustInherit)类,这是自己从System.Drawing.Design.UITypeEditor继承。使用UITypeEditor类,因为需要一些特殊的代码,我们可以把他们到一个基类(辅助)和更容易使用它。
例如当用户按下Esc键,在编辑过程中应取消以前的属性值应返回到IDE的PropertyGrid。或者你总是需要一个类似的代码行IWindowsFormsEditorService服务:
这些工作对于开发人员来说,谁愿意写一个UITypeEditor的迅速不那么明确。我不会多讲这只是提供了基本的辅助类,你可以用它来简化这个过程。 (如果你想看到只是如何使用它,看到的文章。)
下面是代码:
Imports System.Drawing

Imports System.Drawing.Design

Imports System.Windows.Forms

Imports System.Windows.Forms.Design

Imports System.ComponentModel





''' <summary>

''' This is a UITypeEditor base class usefull for simple editing of control 

''' properties in a DropDown or a ModalForm window at design mode (in 

''' Visual Studio IDE). To use this, inherits a class from it and add this

''' attribute to your control property(ies): 

''' <Editor(GetType(MyPropertyEditor), 

'''         GetType(System.Drawing.Design.UITypeEditor))>  

''' </summary><

/span>

Public MustInherit Class PropertyEditorBase

    Inherits System.Drawing.Design.UITypeEditor



    ''' <summary>

    ''' The driven class should provide its edit Control to be shown in the 

    ''' DropDown or DialogForm window by means of this function. 

    ''' If specified control be a Form, it is shown in a Modal Form, otherwise 

    ''' in a DropDown window. This edit control should return its final value 

    ''' at GetEditedValue() method. 

    ''' </summary>

    Protected MustOverride Function GetEditControl(ByVal PropertyName As _

      String, ByVal CurrentValue As Object) As Control



    ''' <summary>The driven class should return the New Edited Value at this 

    ''' function.</summary>

    ''' <param name="EditControl">

    ''' The control shown in DropDown window and used for editing. 

    ''' This is the control you pass in GetEditControl() function.

    ''' </param>

    ''' <param name="OldValue">The original value of the property before 

    ''' editing</param>

    Protected MustOverride Function GetEditedValue(ByVal EditControl As _

      Control, ByVal PropertyName As String, _

               ByVal OldValue As Object) As Object



    Protected IEditorService As IWindowsFormsEditorService



    Private WithEvents m_EditControl As Control

    Private m_EscapePressed As Boolean



    ''' <summary>

    ''' Sets the edit style mode based on the type of EditControl: DropDown or

    ''' Modal(Dialog). 

    ''' Note that the driven class can also override this function and 

    ''' explicitly set its value.

    ''' </summary>

    Public Overrides Function GetEditStyle(ByVal context As _

                               ITypeDescriptorContext) As UITypeEditorEditStyle

        Try

            Dim c As Control

            c = GetEditControl(context.PropertyDescriptor.Name, _

                context.PropertyDescriptor.GetValue(context.Instance))

            If TypeOf c Is Form Then

                Return UITypeEditorEditStyle.Modal 'Using a Modal Form

            End If

        Catch

        End Try

        'Using a DropDown Window (This is the default style)

        Return UITypeEditorEditStyle.DropDown

    End Function



    'Displays the Custom UI (a DropDown Control or a Modal Form) for value 

    'selection.

    Public Overrides Function EditValue(ByVal context As ITypeDescriptorContext,_

      ByVal provider As IServiceProvider, ByVal value As Object) As Object



        Try

            If context IsNot Nothing AndAlso provider IsNot Nothing Then



                'Uses the IWindowsFormsEditorService to display a drop-down

                'UI in the Properties window:

                IEditorService = DirectCast( _

                provider.GetService(GetType(IWindowsFormsEditorService)), _

                                    IWindowsFormsEditorService)



                If IEditorService IsNot Nothing Then



                    Dim PropName As String = context.PropertyDescriptor.Name



                    'get Edit Control from driven class

                    m_EditControl = Me.GetEditControl(PropName, value) 



                    If m_EditControl IsNot Nothing Then



                        m_EscapePressed = False    



                        'Show given EditControl

                        If TypeOf m_EditControl Is Form Then

                            IEditorService.ShowDialog(CType(m_EditControl, Form))

                        Else

                            IEditorService.DropDownControl(m_EditControl)

                        End If



                        If m_EscapePressed Then    'return the Old Value 

                                                   '(because user press Escape)

                            Return value

                        Else 'get new (edited) value from driven class and 

                             'return it

                            Return GetEditedValue(m_EditControl, PropName, value)

                        End If



                    End If 'm_EditControl



                End If 'IEditorService



            End If 'context And provider



        Catch ex As Exception

            'we may show a MessageBox here...

        End Try

        Return MyBase.EditValue(context, provider, value)



    End Function



    ''' <summary>

    ''' Provides the interface for this UITypeEditor to display Windows Forms 

    ''' or to display a control in a DropDown area from the property grid 

    ''' control in design mode.

    ''' </summary>

    Public Function GetIWindowsFormsEditorService() As _

                                                   IWindowsFormsEditorService

        Return IEditorService

    End Function



    ''' <summary>Close DropDown window to finish editing</summary>

    Public Sub CloseDropDownWindow()

        If IEditorService IsNot Nothing Then IEditorService.CloseDropDown()

    End Sub



    Private Sub m_EditControl_PreviewKeyDown(ByVal sender As Object, _

                                 ByVal e As PreviewKeyDownEventArgs) _

                                      Handles m_EditControl.PreviewKeyDown

        If e.KeyCode = Keys.Escape Then m_EscapePressed = True

    End Sub



End Class

如何使用
它有两个MustOverride(摘要)应驱动的类定义的函数。它们是:
Function GetEditControl(ByVal PropertyName As String, _

                        ByVal CurrentValue As Object) As Control

Function GetEditedValue(ByVal EditControl As Control, _

                        ByVal PropertyName As String, _

                        ByVal OldValue As Object) As Object

首先应返回要使用属性编辑器窗口的控制(例如,一个简单的列表框)和第二次下版应该返回属性的新值。驱动类可以使用这些函数的参数信息,返回正确的值。例如,ListBox中的样本,初始项目的下拉列表框选择的基础上的财产CurrentValue。ListBox的编辑示例
下面是一个示例控制使用这个辅助基类定义为"myProperty"的属性编辑:
Imports System.ComponentModel



Public Class XTextBoxA

    Inherits TextBox



    Private m_myProperty As String = ""



    'This property uses our custom UITypeEditor: myListBoxPropertyEditor

    <EditorAttribute(GetType(myListBoxPropertyEditor), 

     GetType(System.Drawing.Design.UITypeEditor))> _

    Public Property myProperty() As String

        Get

            Return m_myProperty

        End Get

        Set(ByVal value As String)

            m_myProperty = value

        End Set

    End Property



End Class







' ////////////////////////////////////////////////////////////////////////////

'   myListBoxPropertyEditor => using a ListBox as EditControl<

/span>

' ////////////////////////////////////////////////////////////////////////////

'

Public Class myListBoxPropertyEditor

    Inherits PropertyEditorBase



    Private WithEvents myListBox As New ListBox 'this is the control to be used 

                                                'in design time DropDown editor



    Protected Overrides Function GetEditControl(ByVal PropertyName As String, _

      ByVal CurrentValue As Object) As Control



        myListBox.BorderStyle = System.Windows.Forms.BorderStyle.None



        'Creating ListBox items... 

        'Note that as this is executed in design mode, performance is not 

        'important and there is no need to cache listbox items if they can 

        'change each time.

        myListBox.Items.Clear()    'clear previous items if any

        myListBox.Items.Add("AAA")

        '... Add other items...



        'Select current item based on CurrentValue of the property:

        myListBox.SelectedIndex = myListBox.FindString(CurrentValue)

        myListBox.Height = myListBox.PreferredHeight



        Return myListBox



    End Function





    Protected Overrides Function GetEditedValue(ByVal EditControl As Control, _

       ByVal PropertyName As String, ByVal OldValue As Object) As Object

        Return myListBox.Text 'return new value for property

    End Function





    Private Sub myTreeView_Click(ByVal sender As Object, ByVal e As _

                                     System.EventArgs) Handles myListBox.Click

        Me.CloseDropDownWindow() 'when user clicks on an item, the edit 

                                 'process is done.

    End Sub



End Class

你应该调用CloseDropDownWindow方法将在适当的事件下拉编辑器窗口。这是为ListBox ListBox的"Click"事件,而是一个TreeView,它可能是在TreeView"的DblClick"事件。注意:
您可以使用这个基类定义编辑器使用任何特殊的控制。例如,你可以定义一个自定义的UserControl设置一个属性,它控制你的主要控制图形视图显示一些图像(而不是一个文本式的枚举列表)。
下载的源代码,看到所有四个样品图1到图4另请参见:帮助开发人员构建定制的扩展设计时,通过智能标记设计师面板组件和控制。

回答

评论会员:罗恩Hubenthal 时间:2011/12/07
最后!我发现了一个全面和工作的例子,如何做到这一点
评论会员:stixoffire 时间:2011/12/07
您好 - 我有一个自定义的控制,从分组框中继承我的工作,我添加了一个属性,当它改变我的设计师。
也应该改变以反映更改。你知道我怎么能抓住这个事件,所以我可以得到的RaiseComponentChnaged事件或东西,将火刷新/重绘
评论会员:?会员4726448 时间:2011/12/07
嗨,我需要知道,如果你能帮助我,如果是可能的返回在属性列表中的窗体的Controls集合

感谢

加布里埃尔Giani
GEMA软件
阿根廷

加布里埃尔Giani
GEMA INFORMATICA
评论会员:Elkay 时间:2011/12/07
在上面的示例中,你有一个自定义控件(XTextboxB),演示了三种不同的属性编辑器
显示所有的编辑三个"子"或"分"作为一个时期,分隔的字符串属性值:

myProperty显示为"Root2.AAA.Item1"(选课后)
- 或 -
myProperty2显示为"Some.Text"(后,你进入这两个词在下拉)

我的问题是这样的:
有什么办法来防止显示分隔的字符串,而同时保留了什么用户输入
评论会员:aguidas 时间:2011/12/07
?您好,
所有好的工作首先

我的问题是,我有一个从database.nbsp数据填充列表框; 我要筛选后外部value.nbsp基于数据; NBSP,这是可能的NBSP? ,我如何可以通过该值类 ? 我trie树剐和几乎成功通过创建自己的属性和属性值的,视为below.nbsp重写GetEditStyle功能; 这工作,但是,我有一个问题,我想在我的属性分配的值不是一个常数,它出现,你只能分配常数attributes.nbsp; 有另一种方式
NBSP?

LT呼叫; codegt;
CONST DESTINATIONID = 1

LT;的DisplayName ("目标字段")的CategoryAttribute("目的地设置"),
DescriptionAttribute("目标字段"),
的DefaultValue( "0"),_
EditorAttribute(的GetType(DestinationListBoxPropertyEditor),的GetType(System.Drawing.Design.UITypeEditor)),_
DestinationID( DESTINATIONID)GT; _
公共财产DestinationFieldID()为整数
LT / codegt;

属性编辑器类
LT; codegt;
公共类DestinationListBoxPropertyEditor
继承PropertyEditorBase

私人WithEvents myListBox作为新的ListBox"这是用于控制设计时间"下拉编辑器
私人_destinationID作为整数= 0

公共覆盖功能GetEditStyle(作为System.ComponentModel.ITypeDescriptorContext BYVAL上下文)作为UITypeEditorEditStyle
如果没有context.PropertyDescriptor.Attributes的GetType(DestinationIDAttribute)是Nothing
NBSP - ; dim属性DestinationIDAttribute = CType运算(context.PropertyDescriptor.Attributes的GetType(DestinationIDAttribute),DestinationIDAttribute)
NBSP ; - ; _destinationID = attribute.DestinationID
如果
NBSP结束;
NBSP ; - ; MyBase.GetEditStyle(上下文)
结束函数

保护覆盖GetEditControl(作为字符串,如对象BYVAL CurrentValue BYVAL的PropertyName)功能System.Windows.Forms.Control的
myListBox.BorderStyle = System.Windows.Forms的BorderStyle.None

"创建的ListBox项目... ...
'请注意,因为这是在设计模式中执行,性能并不重要,有没有需要缓存这些项目,如果他们能够改变每次。
myListBox.Items.Clear()"清除以前的项目,如果任何
NBSP 为每个字段作为DestinationField DestinationFields
NBSP名单(DestinationField)= DestinationField.GetDestinationFields(_de​​stinationID)
NBSP DIM DestinationFields - ; myListBox.Items.Add(field.ID.ToString()放大器;" - "放大器; field.Name)
- ; 下一步

myListBox.SelectedIndex = myListBox.FindString(CurrentValue.ToString)"选择当前项目的基础上的财产
NBSP CurrentValue; myListBox.Height = myListBox.PreferredHeight
返回myListBox
结束函数

保护覆盖功能GetEditedValue(#System.Windows.Forms.Control的EditControl作为对象,BYVAL的PropertyName字符串作为对象,BYVAL OldValue)
返回的CType(myListBox.Text.Substring(0,myListBox.Text.IndexOf(" - ")),整数)'返回新值属性
结束函数

分myTreeView_Click(BYVAL发件人为对象作为System.EventArgs级E)把手
myListBox.Click Me.CloseDropDownWindow()"当用户点击一个项目,在编辑过程中完成。
END SUB

结束类
LT / codegt;

属性:
LT; codegt; { BR} LT AttributeUsage(AttributeTargets.Property GT); _
公共类DestinationIDAttribute
Inherits属性
私人_destinationID为整数

公共ReadOnly属性DestinationID()为整数
获取
- ; 返回_destinationID

高端物业

的Public Sub New(BYVAL iDestinationID为整数)
MyBase的。新建()
_destinationID = iDestinationID
结束小组
结束类
LT / codegt NBSP


- 14时14日(星期三)9月12日修改,2007年
评论会员:aermec 时间:2011/12/07
作为主题,物业类似乎无法识别模式窗体,因为它显示的下拉箭头而不是省略号按钮。
评论会员:micTronic 时间:2011/12/07
我同意,似乎有一些问题。有趣的是,如果我使用一个自定义PropertyGrid控件从工具箱中(相对于VS属性编辑器"窗口),这是基于相同的源,它的工作原理。
评论会员:micTronic 时间:2011/12/07
一些严重的调试后,我有一个想法,为什么会出现这个问题:
在我看来,如果一个类型编辑器导致异常时,Visual Studio禁用该编辑器为本届会议。修复可能的错误后,你将重新启动VS,或重命名属性编辑器类型,以便为VS再次显示一个省略号(...)按钮。
我没有考虑例外是在示例项目的首位,虽然扔在...
评论会员:errorfunktion 时间:2011/12/07
在该文件中:
XTextBoxB.vb线155取代:
myControl.MonthCalendar1.SelectionEnd = D
:
myControl.MonthCalendar1.MinDate myControl.MonthCalendar1.SelectionEnd =

应该OK
评论会员:韦博Tijsma 时间:2011/12/07
。感谢的文章,和我已经创建了一个(文字)转换到C#

如果任何人的兴趣,让我知道wiebeREMOVE@CAPITALStijsma.com(删除的e - mail地址,显然首都)


------------------------------{ BR}勺子?什么勺子?

http://www.netindustry.nl
评论会员:韦博Tijsma 时间:2011/12/07
我已上载这里:

http://www.netindustry.nl/PropertyEditorSharp.zip

S. Serpooshan:如果你喜欢,你可以把它添加到文章
?------------------------------{ BR}勺子?什么勺子?

http://www.netindustry.nl
更新于7月26日,2011下午06:37
评论会员:Lukky 时间:2011/12/07
您好,

能否请您修复的源代码下载链接。

谢谢。好文章。

吕克

吕克莫兰
评论会员:克里斯蒙德 时间:2011/12/07
下载链接已经被固定

欢呼声中,
克里斯蒙德
CodeProject.com:C MVP
评论会员:Lukky 时间:2011/12/07
谢谢你

吕克莫兰
评论会员:hipsvin 时间:2011/12/07
您好,

伟大的文章,我不能下载源
/ /臀围
评论会员:Polymorpher 时间:2011/12/07
{S4}
巴勃罗
而(1){DoTheDo ();}{ BR}
评论会员:siroman 时间:2011/12/07
在我看来,有关此主题的最清晰的文章。许多感谢

如果知识可以创建问题,它是通过无知不是我们能够解决这些问题。 (艾萨克阿西莫夫)
评论会员:visualhint 时间:2011/12/07
您好,

干得好。
这确实简化定义新UITypeEditors的任务。这是值得在PropertyGrid资源列表(会做它ASAP)加入。

最好的问候,
萨科Cadilhac
@ VisualHint

免费
评论会员:devnet247 时间:2011/12/07
您好
我想,只是通知你,这篇文章是更新。现在的新功能,并提供样品!你可能想看一看...
此外,这里是我的新文章:{A6}

评论会员:devnet247 时间:2011/12/07
您好,
我真的很喜欢您control.I已相当一段时间的挣扎,试图找出如何火从属性grid.In的一个形式这种形式,我可能有许多的文本框,组合etc.Do你知道该怎么办并告诉我一个example.thanks
dotnet@devnet247.com

感谢了很多
评论会员:devnet247 时间:2011/12/07
,你应该定义一个UserControl(不是表),你的文本框,组合,添加等,以GetEditControl功能和使用(而不是在SAMPLE1 myListBox控制)。这是一个示例:

Public Class myUserCtrlDropDownEditor

	Inherits DropDownPropertyEditorBase

 

	Private WithEvents myControl As UserControl1 'this is the control to be used in design time DropDown editor



	Protected Overrides Function GetEditControl(ByVal PropertyName As String, ByVal CurrentValue As Object) As System.Windows.Forms.Control

		myControl = New UserControl1

		With myControl

			'.Size = New Size(220, 100)

			.Visible = True

		End With

		Return myControl

	End Function

 

	Protected Overrides Function GetEditedValue(ByVal EditControl As System.Windows.Forms.Control, ByVal PropertyName As String, ByVal OldValue As Object) As Object

		If myControl Is Nothing Then Return OldValue

		If myControl.IsCanceled Then

			Return OldValue

		Else

			Return myControl.TextBox1.Text

		End If

	End Function

 

	Private Sub myForm_VisibleChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles myControl.VisibleChanged

		If myControl.Visible = False Then Me.CloseDropDownWindow()

	End Sub

 

End Class

UserControl的代码可以是这样的:

Public Class UserControl1

 

	Public IsCanceled As Boolean = False

 

	Private Sub ButtonOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonOK.Click

		Me.IsCanceled = False

		Me.Hide()

	End Sub

 

	Private Sub ButtonCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ButtonCancel.Click

		Me.IsCanceled = True

		Me.Hide()

	End Sub

 

End Class