рисование поверх нарисованной графики в winforms

#c# #winforms

#c# #winforms

Вопрос:

привет, я пытаюсь реализовать форму, размер которой изменяется с помощью кодирования. Я использую метод form_paint для рисования границы, но я не могу «закрасить» эту границу. Что я намереваюсь сделать, так это то, что при изменении размера формы с помощью таймера для «плавного изменения размера» граница формы будет обновляться вместе с изменением размера. что мне делать?

     Pen setupControlPen = new Pen(SystemColors.Control, 16);
    Pen setupDimGrayPen = new Pen(Color.DimGray, 5);
  

внутри моего form_paint: // рисует границу формы

     Rectangle newRectangle;
    newRectangle = new Rectangle(new Point(0, 0), new Size(this.Width - 1, this.Height - 1));
    setupGraphics.DrawRectangle(setupDimGrayPen, newRectangle);
  

внутри события щелчка: // я попытался нарисовать поверх уже нарисованной границы.

     Rectangle newRectangle = new Rectangle(new Point(0, 0), new Size(this.Width - 1, this.Height - 1));
    setupGraphics.DrawRectangle(setupControlPen, newRectangle);
  

Спасибо!

обновление: я пытался использовать как событие resize_form, так и таймер для перерисовки, но по-прежнему не могу перерисовывать границу всякий раз, когда я изменяю размер формы.

обновление 2: метод переопределения работает! что касается настройки графики:

     //global space
    Graphics setupGraphics;

    //form_load
    setupGraphics = this.CreateGraphics();

    //so whenever I want to draw something during an event, supposing a button click event to draw a line:
    setupGraphics.DrawLine(pen, point1, point2);
  

Я хотел бы спросить, есть ли какие-либо недостатки в этом методе? или все должно быть сделано внутри метода form_paint?

Комментарии:

1. Установлен ли для вашего FormBorderStyle значение None?

Ответ №1:

Оптимизировано рисование для элементов управления контейнерами. В вашем случае это мешает, вы хотите, чтобы событие рисования срабатывало при изменении размера формы. Сделайте ваш конструктор похожим на это:

     public Form1() {
        InitializeComponent();
        this.ResizeRedraw = true;
        this.DoubleBuffered = true;
    }
  

Или выполните рисование границ в переопределении для OnPaintBackground().

Ответ №2:

Попробуйте переопределить OnPaintBackground метод и установить стиль формы на ResizeRedraw и удвоить буфер:

 public Form1() {
  InitializeComponent();
  this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
}

protected override void OnPaintBackground(PaintEventArgs e) {
  e.Graphics.Clear(SystemColors.Control);

  using (Pen setupDimGrayPen = new Pen(Color.DimGray, 5)) {
    Rectangle newRectangle;
    newRectangle = new Rectangle(new Point(0, 0), new Size(this.Width - 1, this.Height - 1));
    e.Graphics.DrawRectangle(setupDimGrayPen, newRectangle);
  }
}
  

Не очень понятно, откуда setupGraphics берется в вашем сообщении.

Комментарии:

1. Не уверен, что вам следует поощрять создание объектов внутри события рисования. Перо лучше всего делать снаружи и правильно утилизировать вместе с классом. Я бы сказал, что перегрузка DrawRectange, которая принимает x, y, width и height, тоже лучше… Я все же поддержал вас

2. привет, использование метода защищенного переопределения работает без установки стиля и работает даже с двойным буферизацией, установленным в false. С тех пор я отредактировал свой вопрос с помощью setupGraphics.

3. @user776914 Графический объект лучше всего использовать из событий рисования. Если вам нужно нарисовать что-то другое на основе button_click, настройте локальную переменную, чтобы определить, «каким» пером вы хотите рисовать. Вызовите Invalidate() в форме, если не измените размер формы в событии нажатия кнопки, чтобы обновить графику.

Ответ №3:

Так действительно ли ваше событие click изменяет размер формы? Если в форму не вносится никаких изменений, то форма не будет пытаться перерисовываться, вы можете попробовать один из них…

 form.Invalidate();
form.Refresh();
paintControl.Invalidate();
paintControl.Refresh();
  

paintControl предназначен для того, чтобы, если у вас есть элемент управления, отличный от формы, на котором фактически выполняется рисование, вы должны обновлять только наименьший требуемый элемент управления / область

Кроме того, не забудьте установить значение DoubleBuffered равным true для вашей формы / элемента управления

РЕДАКТИРОВАТЬ: я не уверен, что такое setupGraphics? Почему вы не используете объект e.Graphics в аргументах события рисования?

Комментарии:

1. о, я объявил это как: Graphics setupGraphics; в глобальном пространстве. в событии form_load я инициализирую его как setupGraphics = this.CreateGraphics();

2. @user776914: похоже, это может быть фактором, способствующим. Попробуйте использовать e.Graphics или OnPaintBackground, как предложено в другом месте… другой ответ выглядит хорошо