我定义了一个自定义按钮类,它在启用/禁用按钮时设置背景颜色。
在运行时启用外观(A):
运行时禁用外观(B):
设计时间外观始终为(A),与Enabled
属性的值无关。
我希望我的控件能够完全按照运行时出现的方式出现在设计器中。是否有可能,如果是的话,怎么做呢?
这是我尝试过的(只是代码的相关部分):
Public Class StyledButton : Inherits Button
Private p_fEnabled As Boolean
<DefaultValue(True)>
Public Shadows Property Enabled As Boolean
Get
Return p_fEnabled
End Get
Set(value As Boolean)
p_fEnabled = value
MyBase.Enabled = value
UpdateVisualStyle()
End Set
End Property
Private Sub UpdateVisualStyle()
If Me.Enabled Then
'set enabled appearance
Else
'set disabled appearance
End If
End Sub
End Class
答案 0 :(得分:6)
我将解释为什么它会这样做。控件在设计时的行为与在运行时的行为相同。它在Winforms设计器中提供了强大的WYSIWYG支持。但是某些属性在设计时非常笨拙,你实际上并不希望Visible属性生效。非常重要的是,即使在属性窗口中将Visible设置为 False ,控件仍然可见。
这是控件的设计器的核心角色。它拦截了这些困难的属性并模仿它们。在属性网格中显示预期的值,但实际上没有将它们传递给控件的属性设置器。
已启用属性适合此类别。如果没有截获,则无法再选择控件。其他的是ContextMenu,AllowDrop,UserControl的位置和Form,等等。你的阴影替换并没有欺骗设计师,它使用反射来按名称查找属性。所以你的财产没有任何影响,你的财产制定者根本就不会被召唤。
您只能通过覆盖控件的OnPaint()来实现此目的,这样您就可以在设计时显示不同的颜色。一个定制设计师来戳它。然而,一个重要的问题是,替换按钮的渲染器并不简单,该按钮是实现OnPaint()方法的按钮。微软决定让渲染器内部,你无法覆盖它们。
太麻烦了,我建议你把它传递出去。
答案 1 :(得分:1)
shadowed属性在运行时设计工作,而不是在IDE中。您不希望松开Visible = False
的控件,并且即使在Enabled = False
时也希望钻取Button事件。由于IDE无意绘制禁用的控件,因此在更改属性时没有理由调用Invalidate。
由于它在运行时工作,因此在设计器中欺骗它以使用另一个看起来像原始属性的属性:
<Browsable(False), DebuggerBrowsable(DebuggerBrowsableState.Never),
EditorBrowsable(False)>
Public Shadows Property Enabled As Boolean
Get
Return neoEnabled
End Get
Set(value As Boolean)
neoEnabled = value
End Set
End Property
一个新属性,具有IDE的正确名称。
<DisplayName("Enabled")>
Public Property neoEnabled As Boolean
Get
Return p_fEnabled
End Get
Set(value As Boolean)
p_fEnabled = value
UpdateVisualStyle()
MyBase.Enabled = p_fEnabled
End Set
End Property
可悲的是,Enabled
和neoEnabled
都将由Intellisense在代码中提供,但由于它们都做同样的事情,所以它不是什么大问题。测试代码:
Private Sub UpdateVisualStyle()
If p_fEnabled Then
' other interesting stuff
MyBase.BackColor = Color.Lime
Else
MyBase.BackColor = Color.LightGray
End If
MyBase.Invalidate()
End Sub
你可能更多地与我搏斗,并提出更清洁的实施方案。
这会持续与neoEnabled
状态关联的BackColor:
'
'StyledButton1
'
Me.StyledButton1.BackColor = System.Drawing.Color.LightGray
Me.StyledButton1.Enabled = False
Me.StyledButton1.neoEnabled = False
与
Me.StyledButton1.BackColor = System.Drawing.Color.Lime
Me.StyledButton1.Enabled = False
Me.StyledButton1.neoEnabled = True