问题
我的自定义用户控件的属性组显示如下所示的类型名称:
问题
如何删除它们?
我期望与任何其他随机(和专业)用户控件相同的结果,例如krypton工具集,它不显示垃圾:
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
答案 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
提供的摘要/名称覆盖和属性折叠。上面的内容完全是我必须添加到之前的答案中来实现的:
请注意,如果您现在拥有它们,那么很多这种简单性就会消失。 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
,这可能效果不佳。这意味着除了说明目的之外,它们不能真正实现自动实现。 实现这一目标的另一种方法是,它可以提供一个中间立场:
States
集合属性ReadOnlyStyeSet
属性。