开发者

Is there a way to implement a flat TextBox in C#?

I hav开发者_运维问答e a GUI with a flat style for the buttons. I would like to use TextBox controls with the same appearance, but I can't find where can I configure the outer line with. Is there any control in WinForms which can be given FlatStyle? Thanks!


Edit 1

Thanks for the information about FixedSingle border style, but then, how can I change the line properties?


Edit 2

I've implemented a solution with a little bit of both. I would like if you could help improving this class, as I'm not an expert in C# and I find this code somewhat messy. Here is the code:

class BorderTextBox : UserControl
{
    private TextBox m_textBox;
    private int m_borderSize;

    private void ResizeComponent()
    {
        m_textBox.Size = new Size(Size.Width - 2 * m_borderSize, m_textBox.Size.Height);
        Size = new Size(Size.Width, m_textBox.Size.Height + 2 * m_borderSize);
    }

    protected override void OnResize(EventArgs z_event)
    {
        base.OnResize(z_event);
        ResizeComponent();
    }

    public BorderTextBox()
    {
        SuspendLayout();

        // TextBox
        m_textBox = new TextBox();
        m_textBox.BorderStyle = BorderStyle.None;
        m_textBox.Name = "textBox";
        m_textBox.TabIndex = 0;

        // Body
        BackColor = Color.Black;
        Name = "Body";
        Controls.Add(m_textBox);

        ResumeLayout(false);
        PerformLayout();
    }

    public bool UsePasswordStyle
    {
        get { return m_textBox.UseSystemPasswordChar; }
        set { m_textBox.UseSystemPasswordChar = value; }
    }

    public int BorderSize
    {
        get { return m_borderSize; }
        set
        {
            m_borderSize = value;
            m_textBox.Location = new Point(m_borderSize, m_borderSize);
            ResizeComponent();
        }
    }
}

Edit 3

I'm having some problems in implementing the ReadOnly property. I was trying to prevent the edit box to process the OnClick event and show the intermitent cursor inside. When I define the OnClick method inside this class:

class BorderTextBox : UserControl
{
    ...

    protected override void OnClick(EventArgs e)
    {
        if (!ReadOnly)
            base.OnClick(e);
    }        

    ...
}

This method only gets the clicks on the border, but not inside the textBox. Is there a way to catch that events? or how can you remove the event handlers of an element inside your component?

m_textBox.Click -= //the EventHandler we don't want


Set the BorderStyle of the TextBox to FixedSingle.

Update: there isn't an easy way to control the border width of a TextBox, but you can easily create this effect yourself by creating your own UserControl. Basically, you would just set the BackColor of the UserControl to SystemColors.WindowFrame, and then put a TextBox on the control with a BorderStyle of None. In the Resize event of the control, you can then reposition the TextBox so that it leaves a border (which is just the UserControl itself showing through around the edges) of 2 pixels or 5 or whatever you want.

Update 2: I've written a sample UserControl called "ThextBox" ( for Thick-bordered T extBox ) that has an adjustable border:

public partial class ThextBox : UserControl
{
    private TextBox _TextBox;
    private int _BorderWidth = 1;

    [Browsable(true)]
    [DesignerSerializationVisibility
        (DesignerSerializationVisibility.Visible)]
    public override string Text
    {
        get
        {
            return _TextBox.Text;
        }
        set
        {
            _TextBox.Text = value;
        }
    }

    [DesignerSerializationVisibility
        (DesignerSerializationVisibility.Visible)]
    public bool Multiline
    {
        get
        {
            return _TextBox.Multiline;
        }
        set
        {
            _TextBox.Multiline = value;
            ResizeMe();
        }
    }

    [DesignerSerializationVisibility
        (DesignerSerializationVisibility.Visible)]
    public bool UseSystemPasswordChar
    {
        get
        {
            return _TextBox.UseSystemPasswordChar;
        }
        set
        {
            _TextBox.UseSystemPasswordChar = value;
        }
    }

    [DesignerSerializationVisibility
        (DesignerSerializationVisibility.Visible)]
    public char PasswordChar
    {
        get
        {
            return _TextBox.PasswordChar;
        }
        set
        {
            _TextBox.PasswordChar = value;
        }
    }

    [DesignerSerializationVisibility
        (DesignerSerializationVisibility.Visible)]
    public int BorderWidth
    {
        get
        {
            return _BorderWidth;
        }
        set
        {
            _BorderWidth = value;
            ResizeMe();
        }
    }

    public ThextBox()
    {
        InitializeComponent();
        this.BackColor = SystemColors.WindowFrame;
        _TextBox = new TextBox();
        _TextBox.Multiline = false;
        _TextBox.BorderStyle = BorderStyle.None;
        this.Controls.Add(_TextBox);
        ResizeMe();
    }

    protected override void OnFontChanged(EventArgs e)
    {
        base.OnFontChanged(e);
        ResizeMe();
    }

    private void ResizeMe()
    {
        if (this.Multiline)
        {
            _TextBox.Height = this.Height - (2 * _BorderWidth);
        }
        else
        {
            this.Height = _TextBox.Height + (2 * _BorderWidth);
        }
        _TextBox.Width = this.Width - (2 * _BorderWidth);
        _TextBox.Location = new Point(_BorderWidth, _BorderWidth);
    }

    private void ThextBox_Resize(object sender, EventArgs e)
    {
        ResizeMe();
    }
}

To use this code in your project, add a UserControl named "ThextBox" to your project and paste this code over what the designer added. This control has the adjustable border, and it also "plays nicely" with the designer, allowing you to set all its relevant properties in design mode. It also automatically persists things like the text entered, the border width, the password character etc.

If you need to extend this by including additional TextBox-specific properties (such as MaxLength and RightToLeft, just follow the example in the PasswordChar property of this control. One of the advantages of inheriting directly from TextBox instead of UserControl like this would be that your control would automatically have all of the TextBox properties. However, you couldn't do the border that way.


Option 1:

A slightly ugly Hack: (not recommended unless absolutly necessary)

You can have a TextBox with no border and add it into a panel which is x pixels bigger than the TextBox. By altering the Panel (and keeping the TextBox in the middle) you can vary the appearance of the TextBox's border.

Option 2:

A more robust solution, but more of a pain. You could create your own Custom Control and inherit from TextBox. By setting the TextBox's Border to None, you would then be able to draw your own border onto the control. This has the advantage of you being able fto exactly control what the border looks like (e.g. rounded corners etc.) but be warned, this can encroach on the text in the TextBox and look wierd. You could do it something like this:

public class BorderedTextBox: TextBox
{
    protected override void OnPaint( PaintEventArgs pe )
    {
        base.OnPaint(pe);

        // Draw your border here
    }
}


There are border styles you can set on the text box control in c#. On my system, they are already set by default to a "flat" style.


Have you tried setting the BorderStyle property to BorderStyle.FixedSingle or BorderStyle.None?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜