Есть ли способ реализовать плоский TextBox в C #? - PullRequest
3 голосов
/ 21 октября 2009

У меня есть графический интерфейс с плоским стилем для кнопок. Я хотел бы использовать элементы управления TextBox с таким же внешним видом, но не могу найти, где я могу настроить внешнюю линию. Есть ли какой-либо элемент управления в WinForms, который может быть предоставлен FlatStyle? Спасибо!


Редактировать 1

Спасибо за информацию о стиле границы FixedSingle, но как мне изменить свойства линии?


Редактировать 2

Я реализовал решение с небольшим количеством обоих. Я хотел бы, если бы вы могли помочь улучшить этот класс, так как я не эксперт в C #, и я нахожу этот код несколько грязным. Вот код:

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();
        }
    }
}

Редактировать 3

У меня возникли проблемы с реализацией свойства ReadOnly. Я пытался запретить редактору обрабатывать событие OnClick и показывать прерывистый курсор внутри. Когда я определяю метод OnClick внутри этого класса:

class BorderTextBox : UserControl
{
    ...

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

    ...
}

Этот метод получает только щелчки на границе, но не внутри textBox. Есть ли способ поймать эти события? или как вы можете удалить обработчики событий элемента внутри вашего компонента?

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

Ответы [ 4 ]

8 голосов
/ 21 октября 2009

Установите BorderStyle TextBox на FixedSingle.

Обновление : не существует простого способа управления шириной границы TextBox, но вы можете легко создать этот эффект самостоятельно, создав собственный UserControl. По сути, вы просто установите BackColor UserControl на SystemColors.WindowFrame, а затем поместите TextBox на элемент управления с BorderStyle из None. В событии Resize элемента управления вы можете затем переместить TextBox так, чтобы он оставлял границу (которая представляет собой сам UserControl, просвечивающий по краям) в 2 пикселя или 5 или что угодно.

Обновление 2: Я написал пример пользовательского элемента управления под названием "ThextBox" (для Th с выделенным символом T extBox ), который имеет настраиваемую рамку:

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();
    }
}

Чтобы использовать этот код в своем проекте, добавьте UserControl с именем «ThextBox» в свой проект и вставьте этот код поверх того, что добавил дизайнер. Этот элемент управления имеет настраиваемую границу, и он также «хорошо играет» с дизайнером, позволяя вам установить все его соответствующие свойства в режиме конструктора. Также автоматически сохраняются такие вещи, как введенный текст, ширина границы, символ пароля и т. Д.

Если вам нужно расширить это, добавив дополнительные специфичные для TextBox свойства (например, MaxLength и RightToLeft, просто следуйте примеру в свойстве PasswordChar этого элемента управления. Одно из преимуществ наследования непосредственно из TextBox вместо UserControl, как это было бы, ваш элемент управления будет автоматически иметь все свойства TextBox. Однако вы не можете сделать границу таким образом.

2 голосов
/ 21 октября 2009

Вариант 1:

Немного безобразный хак: (не рекомендуется, если абсолютно необходимо)

Вы можете создать TextBox без рамки и добавить его на панель, которая на x пикселей больше, чем TextBox. Изменяя Panel (и удерживая TextBox посередине), вы можете изменять внешний вид границы TextBox.

Вариант 2:

Более надежное решение, но больше боли. Вы можете создать свой собственный пользовательский элемент управления и наследовать от TextBox. Установив для TextBox Border значение None, вы сможете нарисовать свою собственную границу на элементе управления. Преимуществом этого является то, что вы можете точно контролировать, как выглядит граница (например, закругленные углы и т. Д.), Но имейте в виду, что это может нарушить текст в TextBox и выглядеть странно. Вы можете сделать это примерно так:

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

        // Draw your border here
    }
}
0 голосов
/ 21 октября 2009

Вы пытались установить для свойства BorderStyle значение BorderStyle.FixedSingle или BorderStyle.None?

0 голосов
/ 21 октября 2009

Существуют стили границ, которые можно установить в элементе управления текстового поля в c #. В моей системе они по умолчанию уже настроены на «плоский» стиль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...