Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Control's Enabled appearance at design time?

I defined a custom button class, which sets background color when button is enabled/disabled.

Enabled appearance at runtime (A):

enter image description here

Disabled appearance at runtime (B):

enter image description here

Design time appearance is always (A), regardless of the value of Enabled property.

I would like my control to appear in designer exactly the way it would appear at run time. Is it possible and, if so, how can do it?

Here is what I tried (only relevant parts of the code):

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
like image 455
Neolisk Avatar asked Oct 24 '25 19:10

Neolisk


1 Answers

I'll explain why it behaves this way. A control behaves a lot at design time as it does at runtime. It provides the strong WYSIWYG support in the Winforms designer. But certain properties are very awkward at design time, you would not actually want the Visible property to take effect for example. Pretty important that the control remains visible even though you set Visible to False in the Properties Window.

This is a core role of the designer for a control. It intercepts these kind of difficult properties and emulates them. Showing the intended value in the property grid but not actually passing them on to the control's property setter.

The Enabled property fits this category. If it weren't intercepted then the control couldn't be selected anymore. Other ones are ContextMenu, AllowDrop, Location for UserControl and Form, etcetera. Your Shadows replacement doesn't fool the designer, it uses Reflection to find properties by name. So your property doesn't have any effect, your property setter simply never gets called.

You can only truly get this by overriding OnPaint() for the control so you can display a different color at design time. And a custom designer to poke it. A significant hang-up however is that it isn't simple to replace the renderer for the button, the one that implements the OnPaint() method. Microsoft decided to make the renderers internal, you can't override them.

Way too much trouble, I recommend you pass this up.

like image 133
Hans Passant Avatar answered Oct 26 '25 17:10

Hans Passant