【问题标题】:vb .NET custom control inheriting from TextBox doesn't fire Paint event从 TextBox 继承的 vb .NET 自定义控件不会触发 Paint 事件
【发布时间】:2010-08-25 09:01:32
【问题描述】:

我需要一个始终禁用的多行文本框,但它不应该将自身涂成灰色,但我想保持其设计者选择的颜色。

我以前对始终为黑色的标签(没有多行)有相同的要求,所以我从标签继承如下:

Imports System.ComponentModel

   Public Class LabelDisabled
        Inherits Label

        Sub New()
            InitializeComponent()
            Enabled = False
        End Sub

        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            ' always draw it black
            e.Graphics.DrawString(Me.Text, Me.Font, Brushes.Black, 0, 0)
        End Sub

    End Class

效果很好。现在我想要同样的东西,但有一个多行标签,所以我选择从 TextBox 继承:

Imports System.ComponentModel

Public Class CustomControl1
    Inherits TextBox

    Sub New()

        InitializeComponent()
        'Paint never fires anyway
        'Enabled = False
    End Sub


    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        Dim brush As New SolidBrush(Me.ForeColor)
        e.Graphics.DrawString(Me.Text, Me.Font, brush, 0, 0)
    End Sub

End Class

现在在 CustomControl1 - TextBox 继承 - 控件中永远不会触发 Paint 事件。

为什么我无法获得 Paint 事件?

另外,如果我想让 Enabled 属性对用户不可见且不可设置,我会这样做:

<Browsable(False),
DefaultValue(False)>
Public Overloads Property Enabled As Boolean
    Get
        Return False
    End Get
    Set(ByVal value As Boolean)
    End Set
End Property

但是这样,我也不能设置“真正的”启用属性,我的意思是支持字段。

【问题讨论】:

    标签: vb.net custom-controls


    【解决方案1】:

    我找到了解决方案。看起来 TextBox 甚至对子类也禁用了 Paint 事件。但是你可以强制 WM_PAINT 位调用 SetStyle:

    Public Class DisabledTextBox
        Inherits TextBox
    
        Public Sub New()
            InitializeComponent()
    
            Enabled = False
            SetStyle(ControlStyles.Selectable, False)
            SetStyle(ControlStyles.UserPaint, True)
    
        End Sub
    
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            Dim brush As New SolidBrush(Me.ForeColor)
            e.Graphics.DrawString(Me.Text, Me.Font, brush, 0, 0)
        End Sub
    
    End Class
    

    它按预期完美运行:)

    【讨论】:

    • 我还有一些小问题:我的文本框现在被禁用、不可选择且颜色漂亮,但自动换行很糟糕。 DrawString 只是截断一个单词,如果它不能适合当前行,然后继续到下一行(但无论如何该单词已被截断)。我想将 TextBox 的自动换行功能与 DisabledTextBox 的着色功能结合使用。想法?
    • 看起来我今天在回答自己 :) 将 DrawString 替换为: e.Graphics.DrawString(Me.Text, Me.Font, Brush, Me.ClientRectangle) 使用矩形而不是点,提供了很好的自动换行。
    【解决方案2】:

    这是你的答案:

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)
        e.Graphics.FillRectangle(Brushes.LightGray, Me.DisplayRectangle)
        Dim sf As New StringFormat
        sf.FormatFlags = StringFormatFlags.NoWrap
        sf.HotkeyPrefix = Drawing.Text.HotkeyPrefix.Show 'if Mnemonic property is set to true
        sf.HotkeyPrefix = Drawing.Text.HotkeyPrefix.Hide 'or none if Mnemonic property is set to false
        sf.LineAlignment = StringAlignment.Center 'horizontal alignment
        sf.Alignment = StringAlignment.Center ' vertical ...
        Dim rect As Rectangle = Me.DisplayRectangle ' this is your text bounds for setting your text alignement using StringFormat(sf)
        e.Graphics.DrawString("Something", Me.Font, Brushes.DarkOliveGreen, rect, sf)
    End Sub
    

    【讨论】:

    • 添加一些 cmets,你的回答对 OP 自我回答增加了什么?
    猜你喜欢
    • 1970-01-01
    • 2012-12-17
    • 2015-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    相关资源
    最近更新 更多