Невозможно нарисовать на нижней или правой стороне полноэкранной формы - PullRequest
2 голосов
/ 23 декабря 2011

У меня есть код ниже, который должен рисовать линии сверху вниз в полноэкранной форме.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        Graphics g;
        public Form1()
        {
            InitializeComponent();
            g = CreateGraphics();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Pen pen = new Pen(Color.Black);
            for (int i = 0; i < this.ClientSize.Height; i++)
            {
                g.DrawLine(pen, 100, i, 50, i);
            }
        }
    }
}

Форма, о которой идет речь (Форма 1), развернута, без полей и сверху.Результат кода: форма отображается, линии рисуются одна за другой, но когда число i цикла достигает 1055, DrawLine начинает не работать и до тех пор, пока не закончится конец цикла, еще не будет нарисовано, поэтому есть пробелпробел в нижней части формы.

некоторая дополнительная информация

Разрешение моего рабочего стола составляет 1920 x 1080

this.Size = 1920 x 1080

this.ClientSize = 1920 x 1080

Любой желающий может создать пустой проект, установить свойства формы (развернутый, верхний, без полей) и скопировать и вставить этот код, чтобы воспроизвести возникшую проблему.

Ответы [ 3 ]

4 голосов
/ 30 декабря 2011

Вот фиксированный код:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {
//         Graphics g;
        public Form1()
        {
            InitializeComponent();
//            g = CreateGraphics();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Pen pen = new Pen(Color.Black);
            for (int i = 0; i < this.ClientSize.Height; i++)
            {
   //             g.DrawLine(pen, 100, i, 50, i);
                e.Graphics.DrawLine(pen, 100, i, 50, i);
            }
        }
    }
}

Графический объект предназначен для немедленного использования и последующей утилизации. Основная причина в том, что существует реальный контекст устройства Windows (HDC), который используется графическим объектом. Это ограниченный ресурс, и если вы свяжете слишком много в окнах программы, программа будет отключена. Если у вас слишком много программ, использующих слишком много, вы на самом деле аварийно завершите работу пользовательского интерфейса Windows или хотя бы его частей, хотя каждая последующая версия Windows добавляет средства защиты, предотвращающие это. Требуется удалить HDC явно и немедленно с помощью .Dispose или конструкции using, когда вы закончите рисование; к тому времени, когда GC доберется до этого, вы могли бы использовать их все.

Фреймворк создаст графику и избавится от нее в событии рисования. Поэтому, когда вы рисуете краской (рекомендуется), вам не нужно утилизировать графику.

Каждый раз, когда вы используете creategraphics в форме, Graphics.FromImage или аналогичный, вы должны использовать его и распоряжаться им как можно скорее.

Из-за этого дизайна и требований, которые с ним связаны, HDC делает предположения относительно окна в момент его захвата. В свою очередь, окно может развернуться или изменить размер до того, как оно снова появится. Событие рисования также захватывает другое событие из того же дескриптора окна - необычное использование HDC - так что, вероятно, это одна из этих проблем, которая вызывает странное поведение.

2 голосов
/ 29 декабря 2011

Попробуйте использовать e.Graphics из вашего события Paint вместо CreateGraphics() метода.

Пример:

private void Form1_Paint(object sender, PaintEventArgs e) {

  // using your CreateGraphics:
  Pen pen = new Pen(Color.Black);
  for (int i = 0; i < this.ClientSize.Height; i++) {
    g.DrawLine(pen, 100, i, 50, i);
  }

  // using e.Graphics:
  for (int i = 0; i < this.ClientSize.Height; i++) {
    e.Graphics.DrawLine(Pens.Black, 200, i, 250, i);
  }

}

Разница:

enter image description here

1 голос
/ 23 декабря 2011

Насколько мне известно, графические координаты Windows Forms: от y = 0 (самый верхний край) до высоты-1 (самый нижний край) в направлении Y и от x = 0 (самый левый край) до Width-1 (крайний правый край)) в направлении X.

, если это так, первый пример не будет работать, поскольку вы рисуете только за пределами видимой области, однако второй пример будет работать, когда вы рисуете вертикальную линию, которая рисует только один пиксель за пределами видимой области.

Попробуйте изменить на 1079 и посмотреть, если он рендерится.В противном случае попробуйте увеличить y в первом примере и выяснить, где он останавливается.У вас есть форма Chrome, чтобы принять во внимание?Например, форма окна формы с высотой = 1080 может использовать 20 пикселей в строке заголовка и нижнем крае, поэтому фактическая видимая область может быть меньше.

Изменить 1

Изменено после добавления кода в вопрос.Я изменил код следующим образом, и он рисует идеальный прямоугольник в моей системе.Просто из интереса, почему вы создаете графический объект в конструкторе формы?Вы должны использовать тот, который предоставляется аргументами события рисования.Графический объект будет создаваться и удаляться средой выполнения .NET каждый раз, когда форма перерисовывается.

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

Можете ли вы проверить это и сказать мне, если у вас возникла такая же проблема?Кроме того, какие еще свойства мне не хватает (например, Form.Borderstyle и т. Д.), Чтобы получить ту же проблему, что и вы?

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.Paint += new PaintEventHandler(Form1_Paint);
        this.Resize += new EventHandler(Form1_Resize);
    }

    void Form1_Resize(object sender, EventArgs e)
    {
        this.Invalidate(true);
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        using (Pen pen = new Pen(Color.Red, 2.0f))
        {
            e.Graphics.DrawRectangle(pen, new Rectangle(0, 0, ClientSize.Width-1, ClientSize.Height-1));
        }
    }
}
...