Control's Enabled appearance at design time?

前端 未结 2 1172
余生分开走
余生分开走 2021-01-21 19:12

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

Enabled appearance at runtime (A):

相关标签:
2条回答
  • 2021-01-21 19:40

    The shadowed property does work as designed at runtime, just not in the IDE. You would not want to loose controls which are Visible = False, and you would want to drill into Button events even when Enabled = False. Since the IDE has no intention of drawing a disabled control, there is no reason for it to invoke Invalidate when you change the property.

    Since it works at runtime, trick it in the designer to use another property which looks like the original:

    <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
    

    A new property, with the right name for the 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
    

    Sadly, both Enabled and neoEnabled will be offered by Intellisense in code, but since they both do the same thing, its not a big deal. test code:

    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
    

    You have probably wrestled with it more that I, and come up with a cleaner implementation.


    This persists the BackColor associated with neoEnabled state:

    '
    'StyledButton1
    '
    Me.StyledButton1.BackColor = System.Drawing.Color.LightGray
    Me.StyledButton1.Enabled = False
    Me.StyledButton1.neoEnabled = False
    

    versus

    Me.StyledButton1.BackColor = System.Drawing.Color.Lime
    Me.StyledButton1.Enabled = False
    Me.StyledButton1.neoEnabled = True
    
    0 讨论(0)
  • 2021-01-21 19:43

    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.

    0 讨论(0)
提交回复
热议问题