从属性网格可扩展组中删除TypeNames?

时间:2014-12-10 13:21:56

标签: .net vb.net winforms class user-controls

  

问题

我的自定义用户控件的属性组显示如下所示的类型名称:

enter image description here

  

问题

如何删除它们?

我期望与任何其他随机(和专业)用户控件相同的结果,例如krypton工具集,它不显示垃圾:

enter image description here

  

CODE

这是我如何装饰属性网格的代码示例:

Public Class ElektroListBox : Inherits ListBox

    <Category("Appearance")>
    <Description("Enabled state.")>
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
    Public ReadOnly Property StateEnabled() As StateLayout
        Get
            Return Me.stateEnabled1
        End Get
    End Property
    Private ReadOnly stateEnabled1 As StateLayout

    Public Sub New()
        Me.stateEnabled1 = New StateLayout(Me)
    End Sub

End Class

<ToolboxItem(False)>
Public Class StateLayout : Inherits Component

    <Category("Appearance")>
    <Description("The item foreground.")>
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
    Public ReadOnly Property Items As ItemLayout
        Get
            Return Me.items1
        End Get
    End Property
    Private ReadOnly items1 As ItemLayout

    Public Sub New(ByVal listBox As ElektroListBox)
        Me.items1 = New ItemLayout(listBox1)
    End Sub

End Class

1 个答案:

答案 0 :(得分:2)

从我在整个系列问题中看到的是,您正在为已经很复杂的任务(自定义控件)添加复杂性,然后尝试以最简单的方式实现它。这对我来说很少结束。

什么都不做课

以您的Items / ItemLayout类为例。它什么都不做,只是为了摧毁2个孤独的东西。将它们作为ItemState的属性呈现同样有效(并且更容易)。每个 只是Style / StateLayout的一个属性:

[+] StateEnabled
  [-] Cursor
  [-] ForeColor
  [-] BackColor

如果每个那些也有几个子属性,显然就像你的Krypton工具,那么也许我会考虑它。我的意思是将BG + FG折叠到Item只能保存一行。

轻松与强大

可折叠的东西可以由继承自Component的Type提供。但是从TypeConverter继承的ExpandableObjectConverter恰好用于折叠属性。一个更简单的模型,可以完成你想要的大部分工作;从控件类属性开始:

<Browsable(True), EditorBrowsable(EditorBrowsableState.Always),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public Property StateEnabled As ItemState

整个州级:

<TypeConverter(GetType(ItemStateConverter))>
Public Class ItemState
    Inherits ExpandableObjectConverter

    <Browsable(True), NotifyParentProperty(True),
    EditorBrowsable(EditorBrowsableState.Always), DefaultValue(GetType(Color), "")>
    Public Property BackColor As Color

    <Browsable(True), NotifyParentProperty(True),
    EditorBrowsable(EditorBrowsableState.Always), DefaultValue(GetType(Color), "")>
    Public Property ForeColor As Color

    <Browsable(True), NotifyParentProperty(True),
    EditorBrowsable(EditorBrowsableState.Always), DefaultValue(-1)>
    Public Property Pointer As Cursor

    ' serializer requires a simple ctor
    Public Sub New()

    End Sub

    ' see note
    Public Sub New(fg As Color, bg As Color)
        ' default values, if any
        BackColor = bg
        ForeColor = fg
        Pointer = Cursors.Default
    End Sub

End Class

参数化的ctor允许您使用适用的默认值创建类型:

Public Sub New          ' control ctor
   StateEnabled = New ItemState(SystemColors.WindowText, SystemColors.Window)
   ...

Disabled和Selected道具可以使用.HighlightText等作为逻辑起点,而不是Color.Empty。您可以将自定义控件添加到已知用用户颜色主题的现有颜色的表单中,而不是每次都需要逐个设置。

Public Class ItemStateConverter
    Inherits ExpandableObjectConverter

    Public Overrides Function ConvertTo(context As ITypeDescriptorContext,
                               culture As Globalization.CultureInfo,
                               value As Object, destinationType As Type) As Object

        ' need to return something to prevent the
        ' TypeName from displaying.

        If destinationType Is GetType(String) Then
            ' we could provide a Summary of the prop values, but with 3
            ' it gets cluttered:
            '    Dim item As ItemStates = CType(value, ItemStates)

            '    ' ToDo decide the format of collapsed info
            '    Return String.Format("{0}", item.SelectedItem.ForeColor.ToString)

            Return ""
        End If

        Return MyBase.ConvertTo(context, culture, value, destinationType)
    End Function

End Class

多数人。根据类型的不同,VS将使用TypeConverter来提供设计器序列化 - 它不仅仅是Props Window的样式文本。 Inherit Component的一个原因是避免这种情况。但是,这里序列化的只是一个Color,VS可以很好地处理!

我们想要来自 TypeConverter的主要内容是ExpandableObjectConverter提供的摘要/名称覆盖和属性折叠。上面的内容完全是我必须添加到之前的答案中来实现的:

enter image description here

请注意,如果您现在拥有它们,那么很多这种简单性就会消失。 VS不会/不能钻入子项目来序列化它们,这意味着你必须编写一个完整的TypeConverter。为此,我认为StateLayout TypeConverter必须在创建InstanceDescriptor的过程中为每个LayoutItem调用TypeConverter。

以上设计师代码:

Me.ListBoxEx1.StateEnabled.BackColor = System.Drawing.SystemColors.Window
Me.ListBoxEx1.StateEnabled.ForeColor = System.Drawing.SystemColors.WindowText
Me.ListBoxEx1.StateEnabled.Pointer = System.Windows.Forms.Cursors.Default

其它

我不确定为什么你的ItemLayout是ReadOnly。这似乎适得其反:
a)它需要辅助类型引用控件,添加代码和复杂性 b)它降低了功能

如果您将这些内容视为StyleSets,则使用该控件的应用可以允许用户或开发人员定义样式,保存样式并将其应用于控件。 ReadOnly属性可以防止这种情况。

  • 所有基于颜色的道具设置器都应该检查Color.Transparent,这可能效果不佳。这意味着除了说明目的之外,它们不能真正实现自动实现。
  • NotifyParent属性帮助子项通知父类型它已更改。这比对主机控件的引用更简单。

实现这一目标的另一种方法是,它可以提供一个中间立场:

  • 在控件上实现States集合属性
  • 使用Enabled,Disabled和ReadOnly Types种子
  • 这会将它们全部折叠成一个属性,让它们通过标准集合编辑器和道具网格编辑集合。
  • 唯一的&#34;技巧&#34;将禁用“添加”按钮,但您应该已经拥有该工具。
  • 或者,让他们定义他们想要的许多内容,并简单地将某些内容映射到ReadOnlyStyeSet属性。