Потяните границу вокруг Управления на Button_Click

Когда пользователь нажимает мой Проверять Кнопку (в моем C#, WinForm, приложении .net 3.5), я хотел бы потянуть границу вокруг определенного управления, если это пусто. Скажите текстовое поле, которое называют tbxLastName, я думал, что должен был сделать что-то вроде этого->

ControlPaint.DrawBorder(Graphics.FromHwnd(this.Handle), 
    tbxLastName.ClientRectangle, Color.Firebrick, ButtonBorderStyle.Solid);

К сожалению, я понятия не имею, что поместить для Графического Объекта как, что я имею, НИЧЕГО не делает.

Все примеры, с которыми я столкнулся, MSDN - ЗДЕСЬ, имеют этот код в Событии Краски. Как так->

private void panel1_Paint(object sender, PaintEventArgs e)
{    
    ControlPaint.DrawBorder(e.Graphics, this.panel1.ClientRectangle, 
        Color.DarkBlue, ButtonBorderStyle.Solid);
}

Я, однако, только хочу иметь границу, появляются, в то время как определенные условия, встречаются, который начат Button_Click


Столь многие предложения предлагают использовать контейнерный объект для содержания текстового поля и вызова, это - Paint_Event. Я сделал это, и поле появляется, но НЕ вокруг управления. Это появляется в Верхнем левом углу Контейнерного Управления. Вот то, что я делаю->

    private void grpImmunizationCntrl_Paint(object sender, PaintEventArgs e)
    {
        if (lkuNOImmunizationReason.Text.Equals(string.Empty)
        {
           ControlPaint.DrawBorder(
                    e.Graphics, lkuNOImmunizationReason.ClientRectangle,
                        Color.Firebrick, ButtonBorderStyle.Solid);
        }
    }

Править

Это - то, что я придумал объединяющиеся предложения здесь с тем, что работало на меня.

    public static void HighlightRequiredFields(Control container, Graphics graphics, Boolean isVisible)
    {
        Rectangle rect = default(Rectangle);
        foreach (Control control in container.Controls)
        {
            if (control.Tag is string && control.Tag.ToString() == "required")
            {
                rect = control.Bounds;
                rect.Inflate(3, 3);
                if (isVisible && control.Text.Equals(string.Empty))
                {
                    ControlPaint.DrawBorder(graphics, rect, Color.FromArgb(173,216,230), ButtonBorderStyle.Solid);
                }
                else
                {
                    ControlPaint.DrawBorder(graphics, rect, container.BackColor, ButtonBorderStyle.None);
                }
            }

            if (control.HasChildren)
            {
                foreach (Control ctrl in control.Controls)
                {
                    HighlightRequiredFields(ctrl, graphics, isVisible);
                }
            }
        }
    }

Я называю это от Paint_Event из любого Контейнера я должен.

5
задан Refracted Paladin 10 February 2010 в 13:36
поделиться

5 ответов

Я только что сделал кое-что подобное с VB.Net, с помощью этого потока. У меня есть контейнер Panel вокруг каждого набора моих элементов управления, а в OnPaint обработчике Panel я перебираю все дочерние элементы управления в Panel и рисую границы вокруг них, если они имеют тег tag="required". Я отображаю границы только на Edit или New, поэтому я создал параметр fVisible, чтобы включить и выключить их. Когда я хочу это выключить, я вызываю Panel.Refresh(), поэтому он запускает событие OnPaint. Таким образом, все, что мне нужно сделать, это установить теги на требуемых элементах управления во время проектирования, и добавить обработчик для панелей контейнеров, и все это будет работать динамически.

Вот общая функция, которую я вызываю из всех обработчиков событий моей панели OnPaint. (Извините, я знаю, что вы используете C#, а это VB, но это довольно элементарно.)

Friend Sub HighlightRequiredFields(ByVal pnlContainer As Panel, ByVal gr As Graphics, ByVal fVisible As Boolean)
    Dim rect As Rectangle
    For Each oControl As Control In pnlContainer.Controls
        If TypeOf oControl.Tag Is String AndAlso oControl.Tag.ToString = "required" Then
            rect = oControl.Bounds
            rect.Inflate(1, 1)
            If fVisible Then
                ControlPaint.DrawBorder(gr, rect, Color.Red, ButtonBorderStyle.Solid)
            Else
                ControlPaint.DrawBorder(gr, rect, pnlContainer.BackColor, ButtonBorderStyle.None)
            End If
        End If
        If TypeOf oControl Is Panel Then HighlightRequiredFields(DirectCast(oControl, Panel), gr, fVisible)
    Next
End Sub
2
ответ дан 14 December 2019 в 01:07
поделиться
    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
        if (string.IsNullOrEmpty(Text))
        {
            this.BorderStyle = BorderStyle.FixedSingle;
        }
        else 
        {
            this.BorderStyle = BorderStyle.Fixed3D;
        }
    }
1
ответ дан 14 December 2019 в 01:07
поделиться

вы можете использовать поле списка действий в форме и добавлять или удалять собственные рисунки:

// field
List<Action<Graphics>> drawings = new List<Action<Graphics>>();

// on click event:
drawings.Add(delegate(Graphics g) {
    var rect = tbxLastName.Bounds;
    rect.Inflate(1, 1); // make rectange a bit larger than textbox
    ControlPaint.DrawBorder(g, rect, 
    Color.DarkBlue, ButtonBorderStyle.Solid);
});
// make sure you added only once or clear before
panel1.Refresh(); // refresh panel to force painting


// Paint method:
foreach (var draw in drawings) {
    draw(e.Graphics);
}

Таким образом вы можете добавить более одной границы

4
ответ дан 14 December 2019 в 01:07
поделиться

Причина, по которой ваш прямоугольник "пропущен" в текстовом поле, заключается в том, что ClientRectangle содержит только размер элемента управления, а не его местоположение. Попробуйте вместо этого:

private void grpImmunizationCntrl_Paint(object sender, PaintEventArgs e)
{
    if (lkuNOImmunizationReason.Text.Equals(string.Empty)
    {
       ControlPaint.DrawBorder(
                e.Graphics, new Rectangle(lkuNOImmunizationReason.Left, lkuNOImmunizationReason.Top, lkuNOImmunizationReason.ClientRectangle.Width, lkuNOImmunizationReason.ClientRectangle.Height),
                    Color.Firebrick, ButtonBorderStyle.Solid);
    }
}
1
ответ дан 14 December 2019 в 01:07
поделиться

Текстовые поля не вызывают метод OnPaint (см. , примечание раздел на этой странице ). Обойти это можно, поместив текстовое поле на панель, которая немного больше.Затем меняйте цвет фона при каждом нажатии кнопки. В ветке на форумах MSDN есть несколько решений.

Редактировать Чтобы прояснить решение панели, просто создайте панель и добавьте к ней свое текстовое поле: например.

private void MyForm_Load(object sender, EventArgs e)
{
     myPanel.Controls.Add(tbxLastName); //Make sure the panel size is slightly bigger than the text box (so that it looks like a border)
}

Затем обработайте событие нажатия кнопки:

private void myButton_Click(object sender, EventArgs e)
    {
        if (tbxLastName.Text == "")
        {
            myPanel.BackColor = Color.Red;
        }
        else
        {
            myPanel.BackColor = Color.Transparent;
        }
    }
1
ответ дан 14 December 2019 в 01:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: