【问题标题】:Control's Enabled appearance at design time?控件在设计时启用的外观?
【发布时间】:2014-09-29 11:58:54
【问题描述】:

我定义了一个自定义按钮类,它在按钮启用/禁用时设置背景颜色。

在运行时启用外观 (A):

在运行时禁用外观 (B):

无论Enabled 属性的值如何,设计时外观始终为 (A)。

我希望我的控件在设计器中的显示方式与其在运行时的显示方式完全相同。有没有可能,如果有,怎么做?

这是我尝试过的(仅代码的相关部分):

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

【问题讨论】:

  • 你遗漏了最好的部分......设置启用/禁用的过程需要最终通过 Invalidate 调用 Paint
  • @Plutonix:我尝试在UpdateVisualStyle的末尾调用Me.Invalidate(),也尝试了Me.Refresh()。尽管如此,在设计时没有改变行为。还有其他想法吗?
  • 控件在设计器中始终处于启用状态。正如将 Visible 设置为 False 实际上不会对 US 隐藏控件一样,启用状态也不会更改。当鼠标悬停在它们上方时启用 VisualStyles 时,它们也不会glow。有些道具只是RT而已。如果 VisualStyles 处于活动状态,您可能还需要更改 UseVisualStyleBackColor。 (IDE 中没有调用 prop setter - 使用 OnEnableChanged 来查看)
  • @Plutonix:我知道这一点。这就是为什么我创建了自己的 Enabled 属性,它隐藏了原始的 Enabled 属性。所以理论上,设计师应该开始使用新的属性,正确地显示 Enabled 和 Disabled 的外观。
  • 将名称更改为 neoEnabled 即可使用(带无效)

标签: vb.net winforms button design-time appearance


【解决方案1】:

我会解释为什么它会这样。控件在设计时的行为与在运行时一样。它在 Winforms 设计器中提供了强大的 WYSIWYG 支持。但是某些属性在设计时非常尴尬,例如,您实际上并不希望 Visible 属性生效。即使您在属性窗口中将 Visible 设置为 False,该控件仍保持可见非常重要。

这是控件的设计者的核心角色。它拦截了这些困难的属性并模仿它们。在属性网格中显示预期值,但实际上并未将它们传递给控件的属性设置器。

Enabled 属性适合此类别。如果它没有被拦截,则无法再选择控件。其他的是 ContextMenu、AllowDrop、UserControl 和 Form 的位置等。您的阴影替换不会欺骗设计师,它使用反射按名称查找属性。所以你的属性没有任何效果,你的属性设置器根本不会被调用。

只有通过重写控件的 OnPaint() 才能真正实现这一点,这样您就可以在设计时显示不同的颜色。还有一个定制设计师来戳它。然而,一个重要的问题是替换按钮的渲染器并不简单,它实现了 OnPaint() 方法。微软决定让渲染器内部,你不能覆盖它们。

太麻烦了,我建议你放弃这个。

【讨论】:

  • +1。谢谢汉斯,非常好的解释。这部分回答了我的问题:it uses Reflection to find properties by name。虽然我希望设计器显示一些禁用控件和隐藏控件的提示 (Visible = False)。可能是一些特殊颜色和/或图案的边框,具有特殊背景的叠加层,以及 50% 的不透明度等。但我猜微软不会像我看到的那样看到它。 :) 在我当前的程序中禁用按钮意味着一个功能“未实现,但可以实现”。因为它是面向开发人员的工具,所以禁用状态可以作为扩展点。
【解决方案2】:

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

遗憾的是,EnabledneoEnabled 都将由 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

【讨论】:

  • 这不行,您对 BackColor 所做的更改将被保留。它在运行时总是看起来被禁用。
  • 我决定保留自定义属性名称(EnabledCustom)并隐藏原来的Enabled。这样,寻找 Enabled 的人仍然会找到它,并且会知道它是什么(Enabled 属性的自定义实现)。 +1 并接受。
  • 它有效地破坏了 BackColor 作为一个独立的属性,但它是基于新的 Enabled 属性持久化的。 “neoEnabled”是开玩笑的。
  • @Plutonix:在我的实现中,有一个名为 BackColorEnabled 的新属性,还有 ForeColorEnabled,而原始属性 BackColor 和 ForeColor 是隐藏的。禁用的外观被硬编码为灰色的灰色。我认为正确的解决方案是创建一个自定义设计器类,它将控件呈现为禁用状态,但对于此任务来说它看起来太复杂了(考虑到解决方法)。如果有人感兴趣,我会在这里放一个链接:How to: Extend the Appearance and Behavior of Controls in Design Mode
猜你喜欢
  • 2011-01-03
  • 1970-01-01
  • 2012-08-12
  • 1970-01-01
  • 1970-01-01
  • 2020-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多