-1

Doing a project of a client and a weird request has come from them. they want a feature in the winform(vb.net or c#) that when display mode will be on no text box will be editable as well as selectable. I know changing the enabled property to false will solve it, but they want it to be active but not selectable. Can any one give me some idea onto this?

Metzner88
  • 3
  • 4
  • 1
    `they want it to be active but not selectable` - If a user cannot select nor modify a textbox's contents then it isn't very active any longer, now is it? So what's so wrong with `Enabled = False` then? – Visual Vincent Aug 30 '17 at 21:06
  • I asked them too, but they want it. Any way I think I have to create a custom text box control for them as they want the color of text intact, my client likes the chrimson color very much :). Custom text box control may be solve my problem. I will then disable the box and also will add a new property to set text color when the text box will be disabled. I think it is the proper solution, what do you say? – Metzner88 Aug 30 '17 at 21:25
  • I don't know... It sounds like a hackish workaround trying to keep the text intact when being disabled (don't even know if it's possible, it's the runtime that's responsible for painting it that way). If it were me I'd create a custom `TextBox`, set `ReadOnly = True` and try to block selection. This answer should be convertible to VB.NET using for instance [**Telerik**](http://converter.telerik.com): https://stackoverflow.com/a/31419879/3740093 – Visual Vincent Aug 30 '17 at 21:32
  • This seems to answer preventing textbox selecting: https://stackoverflow.com/questions/13256720/disable-selecting-text-in-a-textbox – NetMage Aug 30 '17 at 21:42
  • Thanks for that link, yeah I think creating a custom text box is the only way to solve this type of weird client's request. Though the feature is not so useful but they wants it in their application. I am going to ask them some more penny as an additional request fulfillment. Thanks again, I will load the custom code here after completing the work. – Metzner88 Aug 30 '17 at 21:44
  • @NetMage thanks for the link, this link has some great ideas to solve this type of weird problem. – Metzner88 Aug 30 '17 at 21:49
  • Visual Vincent and @NetMage, I have post a code here as the final code for the textbox control. You can consider view it for any improvement or any necessary correction. Thanks in advance. – Metzner88 Aug 31 '17 at 21:46

4 Answers4

0

I guess you need to override the onPaint event!

If I am not mistaken, this should be so simple and no need to create a custom control, Just open the Form Designer file and use the following:

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)
        TextBox1.BackColor = Color.White
End Sub

You might loop all controls which should be easy.

M. Waheed
  • 877
  • 1
  • 8
  • 8
  • I got a nice solution, some funny too, it will add some lines of codes though, but not so much like writing a new control. There will be a text box and label along with a panel of same size of the text box. When the editing mode will be on, the user will see the text box to edit what ever he wants, then when the display mode will be on, the user will see the label and the panel, where the label will have the same color of the text box text color and the same value of the text box. A nice workaround but instead a custom text box will be more better than this. Any way thanks. – Metzner88 Aug 30 '17 at 22:45
0

I see from your comment to the other answer that you have selected a control swapping solution. However I thought that the following may be of use to someone seeking a similar behavior.

This control will not prevent programmatic selection of TextBox control, but will prevent normal user selection via the mouse and keyboard. Use the Selectable property to enable/disable selection.

Public Class TB : Inherits TextBox
    Public Sub New()
        SetStyle(ControlStyles.Selectable, False)
    End Sub

    Public Property Selectable As Boolean
        Get
            Return GetStyle(ControlStyles.Selectable)
        End Get
        Set(value As Boolean)
            SetStyle(ControlStyles.Selectable, value)
        End Set
    End Property

    Private Const WM_MOUSEACTIVATE As Integer = &H21
    Private Const NOACTIVATEANDEAT As Integer = &H4

     Protected Overrides Sub WndProc(ByRef m As Message)
        If m.Msg = WM_MOUSEACTIVATE AndAlso Not Me.Selectable Then
            m.Result = New IntPtr(NOACTIVATEANDEAT)
            Return
        End If
        MyBase.WndProc(m)
     End Sub
End Class
TnTinMn
  • 11,522
  • 3
  • 18
  • 39
  • Thanks this is the right thing I was thinking of and which will be useful for anyone, who need this type of implementation. – Metzner88 Aug 31 '17 at 10:34
  • I have post a code here as the final code for the textbox control. You can consider view it for any improvement or any necessary correction. Thanks in advance. – Metzner88 Aug 31 '17 at 21:46
0

Though TnTinMn has solved my problem but I got a nice link about the keeping the text color intact of text box, and probably the wow things about how a new approach has been taken to address this issue. Here is the link, https://www.experts-exchange.com/articles/10842/A-New-Approach-for-Custom-Colors-in-a-Disabled-VB-Net-WinForms-TextBox.html Author Mike Tomlinson has nicely detailed every steps he wrote in his post.

TnTinMn approach is also useful to solve that type of problem.

Metzner88
  • 3
  • 4
0
/*Here is the full code of new text box control.
Inspired by the Post made by Mike Tomlinson and Ehtesham*/
using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
namespace MyTxtBoxControl
{
public class extTextBox:TextBox
{
#region New Utilisable Variables
    const int WM_ENABLE = 0xa; //in vb &HA
    Color _foreColor;
    Color _foreColorDisabled;
    Boolean _ColorIsSaved = false;
    Boolean _settingColor = false;
    //included a default text
    //that will be shown when no text will be entered
    String _DefaultText = "Enter Text Here";
#endregion
#region Constructor of the new textbox control
    public extTextBox()
    {
        base.Text = this._DefaultText;
        this._foreColor = this.ForeColor;
        //My Text Control Box event handlers
        this.TextChanged += new EventHandler(onTextChanged);
        this.KeyPress += new KeyPressEventHandler(onKeyPress);
        this.LostFocus += new EventHandler(onTextChanged);
        this.VisibleChanged+=new EventHandler(onVisibleChanged);
    }
#endregion
#region Event Handler Methods
    protected void onTextChanged(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(this.Text))
            {
                this.ForeColor = this._foreColor;
            }
            else
            {
                this.TextChanged-=new EventHandler(onTextChanged);
                base.Text = this._DefaultText;
                this.TextChanged+=new EventHandler(onTextChanged);
            }
        }
        protected void onKeyPress(object sender, EventArgs e)
        {
            //Replaces empty text as the firt key will be pressed
            string strings = base.Text.Replace(this._DefaultText, string.Empty);
            this.TextChanged -= new EventHandler(onTextChanged);
            this.Text=strings;
            this.TextChanged += new EventHandler(onTextChanged);
        }
        protected void onVisibleChanged(object sender, EventArgs e)
        {
            if (!(this._ColorIsSaved & this.Visible))
            {
                _foreColor = this.ForeColor;
                _foreColorDisabled = this.ForeColor;
                _ColorIsSaved = true;

                if (!(this.Enabled))
                {
                    this.Enabled = true; //Enable to initialize the property then
                    this.Enabled = false;//disabling 
                }
                setColor();
            }
        }

        protected override void OnForeColorChanged(EventArgs e)
        {
            base.OnForeColorChanged(e);
            if (!_settingColor)
            {
                _foreColor = this.ForeColor;
                setColor();
            }
        }
        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);
            setColor();
        }
#endregion
#region Setcolor method
        private void setColor()
        {
            if (_ColorIsSaved)
            {
                _settingColor = true;
                if (this.Enabled)
                {
                    this.ForeColor = this._foreColor;
                }
                else
                {
                    this.ForeColor = this._foreColorDisabled;
                }
                _settingColor = false;
            }
        }
#endregion
#region TextBox Encapsulation Parameter overriding 
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams CP = default(CreateParams);
                if (!this.Enabled)
                {
                    this.Enabled = true;
                    CP = base.CreateParams;
                    this.Enabled = false;
                }
                else
                {
                    CP = base.CreateParams;
                }
                return CP;
            }
        }
#endregion
#region supressing WM_ENABLE message
        protected override void WndProc(ref Message mesg)
        {
            switch (mesg.Msg)
            {
                case WM_ENABLE:
               // Prevent the message from reaching the control,
               // so the colors don't get changed by the default procedure.
                    return;// <-- suppress WM_ENABLE message
            }
            base.WndProc(ref mesg);//system you can do the rest disable process
        }
#endregion
#region User Defined Properties
        ///<summery>
        ///Property to set Text
        ///</summery>
        [Browsable(true)]
        [Category("Properties")]
        [Description("Set TextBox Text")]
        [DisplayName("Text")]
        public new String Text
        {
            get
            {
                //It is required for validation for TextProperty
                return base.Text.Replace(this._DefaultText, String.Empty);
            }
            set
            {
                base.Text = value;
            }
        }
        ///<summery>
        ///Property to get or Set Default text at Design/Runtime
        ///</summery>
        [Browsable(true)]
        [Category("Properties")]
        [Description("Set default Text of TextBox, it will be shown when no text will be entered by the user")]
        [DisplayName("Default Text")]
        public String DefaultText
        {
            get
            {
                return this._DefaultText;
            }
            set
            {
                this._DefaultText = value;
                base.OnTextChanged(new EventArgs());
            }
        }
#endregion
}

}

Metzner88
  • 3
  • 4