继承System.Windows.Forms.TextBox,想更改其Readonly改变时的背景色.

时间:2022-02-24 21:11:11
我用了以下两个方法,可是都不好用
1.重写OnReadOnlyChanged,导致重绘控件。
    Protected Overrides Sub OnReadOnlyChanged(ByVal e As System.EventArgs)
        MyBase.OnReadOnlyChanged(e)

        If Not Me.ReadOnly Then
            Me.SetStyle(ControlStyles.UserPaint, True)
        Else
            Me.SetStyle(ControlStyles.UserPaint, False)
        End If

        Me.Invalidate()
    End Sub

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)
        Dim TextBrush As SolidBrush
        Dim sf As New StringFormat

        Select Case Me.TextAlign
            Case HorizontalAlignment.Center
                sf.Alignment = StringAlignment.Center
            Case HorizontalAlignment.Left
                sf.Alignment = StringAlignment.Near
            Case HorizontalAlignment.Right
                sf.Alignment = StringAlignment.Far
        End Select

        Dim rDraw As RectangleF = RectangleF.op_Implicit(Me.ClientRectangle)
        rDraw.Inflate(0, 0)

        If Not Me.RReadOnly Then
            TextBrush = New SolidBrush(Me.ForeColor)
        Else
            TextBrush = New SolidBrush(Me.ForeColor)
            Dim BackBrush As New SolidBrush(Me.LockColor)
            e.Graphics.FillRectangle(BackBrush, 0.0F, 0.0F, Me.Width, Me.Height)
        End If
        e.Graphics.DrawString(Me.Text, Me.Font, TextBrush, rDraw, sf)
    End Sub

2.重写ReadOnly属性,调用PropertyChanged事件
Implements INotifyPropertyChanged
Private me_ReadOnly As Boolean = False

Public Shadows Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

    Private Sub NotifyPropertyChanged(ByVal info As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
    End Sub

Public Overloads Property [ReadOnly]() As Boolean
        Get
            Return me_ReadOnly
        End Get
        Set(ByVal Value As Boolean)
            me_ReadOnly = Value
            If Not (Value = me_ReadOnly) Then
                me_ReadOnly = Value
                NotifyPropertyChanged("ReadOnly")
            End If

        End Set
    End Property

Public Sub ReadOnly_OnChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Handles Me.PropertyChanged
        If Not me_ReadOnly Then
            Me.BackColor = Color.White
        Else
            Me.BackColor = Me.LockColor
        End If
        Me.Invalidate()
    End Sub

还望高人指点,如何不让TextBox设置ReadOnly时,背景色变成灰色,而变成自己自定义的颜色。(LockColor)

21 个解决方案

#1


如下就可以了:
this.readOnlyTextBox1.ReadOnly = true;
this.readOnlyTextBox1.BackColor = SystemColors.Window;

#2


哦,VB.NET:

Me.textBox1.ReadOnly = true
Me.textBox1.BackColor = SystemColors.Window

#3


我做的是自定义控件,继承的System.Windows.Forms.TextBox,

#4


而且我想实现的效果是在设计是,改变ReadOnly属性,背景色也跟着改变

#5


你可以这样来写你的类:

Public Class ReadOnlyTextBox
    Inherits TextBox

    Private m_BackColor As Color

    Public Sub New()
        Me.m_BackColor = Color.Red
    End Sub

    Protected Overrides Sub OnReadOnlyChanged(ByVal e As EventArgs)
        MyBase.OnReadOnlyChanged(e)
        Me.BackColor = Me.m_BackColor
    End Sub

    Public Property MyBackColor As Color
        Get
            Return Me.m_BackColor
        End Get
        Set(ByVal value As Color)
            Me.m_BackColor = value
            Me.BackColor = Me.m_BackColor
        End Set
    End Property
End Class

#6


学习!

#7


谢谢hbxtlhx热心解答
可是你的方法还是不好用
当ReadOnly由默认的Flase设为True时,控件变成了红色
可是再由True设回Flase时,颜色还是红色

#8


Public Class ReadOnlyTextBox
    Inherits TextBox

    Private _ReadOnlyColor As Color=Color.Red
    Private _BackColor As Color

    Public Sub New()
        _BackColor = BackColor
    End Sub

    Protected Overrides Sub OnReadOnlyChanged(ByVal e As EventArgs)
        MyBase.OnReadOnlyChanged(e)
        Me.BackColor=iif(ReadOnly, _ReadOnlyColor, _BackColor)
    End Sub

    Public Overrides Property BackColor As Color
        Get
            Return MyBase.BackColor
        End Get
        Set(ByVal value As Color)
            MyBase.BackColor = value
            _BackColor = value
        End Set
    End Property
End Class

#9


顶一下

#10


只是提供了一个实现的途径.

你可以按你的逻辑自己来实现啊,在我的机子上测试是符合要求的.

#11


hbxtlhx的方法应该可以解决的,只是再加一个判断,是变成True还是变成False。

#12


最后用一下方法搞定了,可是还是有BUG
Protected Overrides Sub OnReadOnlyChanged(ByVal e As System.EventArgs)
            MyBase.OnReadOnlyChanged(e)
            If Me.ReadOnly Then
                Me.SetStyle(ControlStyles.UserPaint, True)
            Else
                Me.SetStyle(ControlStyles.UserPaint, False)
            End If

            Me.Invalidate()
        End Sub

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
            Dim TextBrush As SolidBrush
            Dim sf As New StringFormat

            Select Case Me.TextAlign
                Case HorizontalAlignment.Center
                    sf.Alignment = StringAlignment.Center
                Case HorizontalAlignment.Left
                    sf.Alignment = StringAlignment.Near
                Case HorizontalAlignment.Right
                    sf.Alignment = StringAlignment.Far
            End Select

            Dim rDraw As RectangleF = RectangleF.op_Implicit(Me.ClientRectangle)
            rDraw.Inflate(0, 0)

            If Not Me.ReadOnly Then
                TextBrush = New SolidBrush(Me.ForeColor)
            Else
                TextBrush = New SolidBrush(Me.ForeColor)
                Dim BackBrush As New SolidBrush(Me.LockedBackColor)
                e.Graphics.FillRectangle(BackBrush, 0.0F, 0.0F, Me.Width, Me.Height)
            End If
            e.Graphics.DrawString(Me.Text, Me.Font, TextBrush, rDraw, sf)
        End Sub

以上代码实现了,改变ReadOnly属性时,背景色随之变化。
但是,程序运行时,ReadOnlyTextBox获得焦点时,发生两种颜色重叠的现象(Control和我的LockedColor)
分别在LostFocus和GotFocus中控制,均无法解决

#13


jf

#14


有兴趣的朋友可以看看这诡异的TextBox
我传到yahoo相册了
http://photos.i.cn.yahoo.com/photo-DXGAOf0ifq3K.CPXfiawJhzCqPI-?cq=1&aid=f1e7&pid=931fcnb.jpg

#15


哪位高人能帮我解决问题,这100分加上我的万分感激全送给他

#16


那就是我!

#17


Dim rDraw As RectangleF = RectangleF.op_Implicit(Me.ClientRectangle)
rDraw.Inflate(0, 0)

If Not Me.ReadOnly Then
TextBrush = New SolidBrush(Me.ForeColor)
Else
TextBrush = New SolidBrush(Me.ForeColor)
Dim BackBrush As New SolidBrush(Me.LockedBackColor)
e.Graphics.FillRectangle(BackBrush, 0.0F, 0.0F, Me.Width, Me.Height)
End If
e.Graphics.DrawString(Me.Text, Me.Font, TextBrush, rDraw, sf)
End Sub

为什么我重绘控件之后,字向上移动了,哪里不对吗?

#18


Imports System.Runtime.InteropServices
Public Class TextBoxEx
    Inherits TextBox

    Private _ReadOnly As Boolean = False
    Private _DisableBackColor = SystemColors.Control
    Private _DisableForeColor As Color = Color.Black

    <DllImport("user32.dll")> _
       Public Shared Function SendMessage(ByVal hWnd As HandleRef, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
    End Function

    Public Shadows Property [ReadOnly]() As Boolean
        Get
            Return _ReadOnly
        End Get
        Set(ByVal Value As Boolean)
            If _ReadOnly <> Value Then
                If Not Value Then
                    Me.BackColor = Color.White
                    Me.ForeColor = Color.Black
                Else
                    Me.BackColor = Me._DisableBackColor
                    Me.ForeColor = Me._DisableForeColor
                End If
                Me._ReadOnly = Value
                Me.SendMessage(New HandleRef(Me, Me.Handle), &HCF, IIf(Value, -1, 0), 0)
                Me.Refresh()
            End If
        End Set
    End Property

    Public Property DisableBackColor() As Color
        Get
            Return Me._DisableBackColor
        End Get
        Set(ByVal Value As Color)
            Me._DisableBackColor = Value
        End Set
    End Property

    Public Property DisableForeColor() As Color
        Get
            Return Me._DisableForeColor
        End Get
        Set(ByVal Value As Color)
            Me._DisableForeColor = Value
        End Set
    End Property
End Class

#19


还要再重写下Enabled属性
Private _enabled as Boolean=True
Public Shadows Property Enabled() As Boolean
     Get
         Return Me._enabled
     End Get
     Set(ByVal Value As Boolean)
         Me._enabled = Value
         Me.ReadOnly = Not Value
     End Set
 End Property

#20


最后用了xfyxq(小小旗)的方法
即简单,又实用,解决了

#21


不过仍然很感谢hbxtlhx
因为他坚持真理
而且为了助人亲自尝试

#1


如下就可以了:
this.readOnlyTextBox1.ReadOnly = true;
this.readOnlyTextBox1.BackColor = SystemColors.Window;

#2


哦,VB.NET:

Me.textBox1.ReadOnly = true
Me.textBox1.BackColor = SystemColors.Window

#3


我做的是自定义控件,继承的System.Windows.Forms.TextBox,

#4


而且我想实现的效果是在设计是,改变ReadOnly属性,背景色也跟着改变

#5


你可以这样来写你的类:

Public Class ReadOnlyTextBox
    Inherits TextBox

    Private m_BackColor As Color

    Public Sub New()
        Me.m_BackColor = Color.Red
    End Sub

    Protected Overrides Sub OnReadOnlyChanged(ByVal e As EventArgs)
        MyBase.OnReadOnlyChanged(e)
        Me.BackColor = Me.m_BackColor
    End Sub

    Public Property MyBackColor As Color
        Get
            Return Me.m_BackColor
        End Get
        Set(ByVal value As Color)
            Me.m_BackColor = value
            Me.BackColor = Me.m_BackColor
        End Set
    End Property
End Class

#6


学习!

#7


谢谢hbxtlhx热心解答
可是你的方法还是不好用
当ReadOnly由默认的Flase设为True时,控件变成了红色
可是再由True设回Flase时,颜色还是红色

#8


Public Class ReadOnlyTextBox
    Inherits TextBox

    Private _ReadOnlyColor As Color=Color.Red
    Private _BackColor As Color

    Public Sub New()
        _BackColor = BackColor
    End Sub

    Protected Overrides Sub OnReadOnlyChanged(ByVal e As EventArgs)
        MyBase.OnReadOnlyChanged(e)
        Me.BackColor=iif(ReadOnly, _ReadOnlyColor, _BackColor)
    End Sub

    Public Overrides Property BackColor As Color
        Get
            Return MyBase.BackColor
        End Get
        Set(ByVal value As Color)
            MyBase.BackColor = value
            _BackColor = value
        End Set
    End Property
End Class

#9


顶一下

#10


只是提供了一个实现的途径.

你可以按你的逻辑自己来实现啊,在我的机子上测试是符合要求的.

#11


hbxtlhx的方法应该可以解决的,只是再加一个判断,是变成True还是变成False。

#12


最后用一下方法搞定了,可是还是有BUG
Protected Overrides Sub OnReadOnlyChanged(ByVal e As System.EventArgs)
            MyBase.OnReadOnlyChanged(e)
            If Me.ReadOnly Then
                Me.SetStyle(ControlStyles.UserPaint, True)
            Else
                Me.SetStyle(ControlStyles.UserPaint, False)
            End If

            Me.Invalidate()
        End Sub

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
            Dim TextBrush As SolidBrush
            Dim sf As New StringFormat

            Select Case Me.TextAlign
                Case HorizontalAlignment.Center
                    sf.Alignment = StringAlignment.Center
                Case HorizontalAlignment.Left
                    sf.Alignment = StringAlignment.Near
                Case HorizontalAlignment.Right
                    sf.Alignment = StringAlignment.Far
            End Select

            Dim rDraw As RectangleF = RectangleF.op_Implicit(Me.ClientRectangle)
            rDraw.Inflate(0, 0)

            If Not Me.ReadOnly Then
                TextBrush = New SolidBrush(Me.ForeColor)
            Else
                TextBrush = New SolidBrush(Me.ForeColor)
                Dim BackBrush As New SolidBrush(Me.LockedBackColor)
                e.Graphics.FillRectangle(BackBrush, 0.0F, 0.0F, Me.Width, Me.Height)
            End If
            e.Graphics.DrawString(Me.Text, Me.Font, TextBrush, rDraw, sf)
        End Sub

以上代码实现了,改变ReadOnly属性时,背景色随之变化。
但是,程序运行时,ReadOnlyTextBox获得焦点时,发生两种颜色重叠的现象(Control和我的LockedColor)
分别在LostFocus和GotFocus中控制,均无法解决

#13


jf

#14


有兴趣的朋友可以看看这诡异的TextBox
我传到yahoo相册了
http://photos.i.cn.yahoo.com/photo-DXGAOf0ifq3K.CPXfiawJhzCqPI-?cq=1&aid=f1e7&pid=931fcnb.jpg

#15


哪位高人能帮我解决问题,这100分加上我的万分感激全送给他

#16


那就是我!

#17


Dim rDraw As RectangleF = RectangleF.op_Implicit(Me.ClientRectangle)
rDraw.Inflate(0, 0)

If Not Me.ReadOnly Then
TextBrush = New SolidBrush(Me.ForeColor)
Else
TextBrush = New SolidBrush(Me.ForeColor)
Dim BackBrush As New SolidBrush(Me.LockedBackColor)
e.Graphics.FillRectangle(BackBrush, 0.0F, 0.0F, Me.Width, Me.Height)
End If
e.Graphics.DrawString(Me.Text, Me.Font, TextBrush, rDraw, sf)
End Sub

为什么我重绘控件之后,字向上移动了,哪里不对吗?

#18


Imports System.Runtime.InteropServices
Public Class TextBoxEx
    Inherits TextBox

    Private _ReadOnly As Boolean = False
    Private _DisableBackColor = SystemColors.Control
    Private _DisableForeColor As Color = Color.Black

    <DllImport("user32.dll")> _
       Public Shared Function SendMessage(ByVal hWnd As HandleRef, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
    End Function

    Public Shadows Property [ReadOnly]() As Boolean
        Get
            Return _ReadOnly
        End Get
        Set(ByVal Value As Boolean)
            If _ReadOnly <> Value Then
                If Not Value Then
                    Me.BackColor = Color.White
                    Me.ForeColor = Color.Black
                Else
                    Me.BackColor = Me._DisableBackColor
                    Me.ForeColor = Me._DisableForeColor
                End If
                Me._ReadOnly = Value
                Me.SendMessage(New HandleRef(Me, Me.Handle), &HCF, IIf(Value, -1, 0), 0)
                Me.Refresh()
            End If
        End Set
    End Property

    Public Property DisableBackColor() As Color
        Get
            Return Me._DisableBackColor
        End Get
        Set(ByVal Value As Color)
            Me._DisableBackColor = Value
        End Set
    End Property

    Public Property DisableForeColor() As Color
        Get
            Return Me._DisableForeColor
        End Get
        Set(ByVal Value As Color)
            Me._DisableForeColor = Value
        End Set
    End Property
End Class

#19


还要再重写下Enabled属性
Private _enabled as Boolean=True
Public Shadows Property Enabled() As Boolean
     Get
         Return Me._enabled
     End Get
     Set(ByVal Value As Boolean)
         Me._enabled = Value
         Me.ReadOnly = Not Value
     End Set
 End Property

#20


最后用了xfyxq(小小旗)的方法
即简单,又实用,解决了

#21


不过仍然很感谢hbxtlhx
因为他坚持真理
而且为了助人亲自尝试