Я не могу вырваться из своего ClipRectangle, и я хочу плакать - PullRequest
12 голосов
/ 26 апреля 2011

При переопределении метода OnPaint пользовательского элемента управления мне предоставляется PaintEventArgs , который содержит объект Graphics и ClipRectangle.ClipRectangle слишком мал для моих вкусов, поэтому я хочу либо расширить его, скажем, на 100 пикселей, либо полностью его игнорировать.

Независимо от того, что я делаю, я не могу вырваться из ClipRectangle,До сих пор я пробовал:

e.ClipRectangle.Inflate(100, 0);
e.Graphics.ResetClip();
e.Graphics.SetClip(new Rectangle(x, y, w, h));

Родительский элемент управления вызывает Invalidate (true) (для принудительной отмены всех дочерних элементов управления потомков).

Я также сделалнекоторые погуглили и посмотрели на сайте Боба Пауэлла, но не смогли найти nuffin.

ResetClip сбрасывает область отсечения для объекта Graphics в бесконечно большой Rectangle, но объект Graphics продолжает радостно использовать предоставленный ClipRectangle.

Справка.

Ответы [ 2 ]

5 голосов
/ 26 апреля 2011

Прямоугольник - это структура, а не класс - он передается как значение, поэтому вызов e.ClipRectangle.Inflate(100, 0); не может помочь даже теоретически.

Следующее, что вам нужно знать, это то, что e.Graphics относится к аппаратному устройствуконтекст, поэтому Windows не позволит вам расширить область рисования.Решение состоит в том, чтобы получить контекст устройства родительского окна и затем нарисовать, где вы хотите.Вот как это сделать:

[DllImport("User32.dll")]
static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("User32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);

IntPtr dcPtr = GetDC(this.ParentForm.Handle);
Graphics g = Graphics.FromHdc(dcPtr);

// your code here

// don't forget to release it
g.Dispose();
ReleaseDC(this.ParentForm.Handle, dcPtr);
5 голосов
/ 26 апреля 2011

Резюме: Похоже, у вас есть дочерний элемент управления с пользовательским методом рисования.Вы хотите нарисовать элемент управления в области, которая больше, чем границы самого элемента управления.Например, если вы разместите свой элемент управления в (10, 10, 100, 100), вы хотите нарисовать область в (0, 10, 110, 100).

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

Что вы можете сделать: один из вариантов - переопределить метод create родительского окна и удалитьстиль окна WS_CLIPCHILDREN (0x02000000), затем нарисуйте дочерний элемент в методе рисования родителя.

Другой вариант - просто расширить область дочернего окна, чтобы она охватила область, которую вы хотите нарисовать.Если вы также переопределите метод OnPaintBackground вашего элемента управления, вы можете запретить фоновой краске очистить отображение родительского объекта.Это проблематично, так как родитель будет обрезать область ребенка, а не обновлять ее.Таким образом, вам все еще нужно удалить родительский WS_CLIPCHILDREN, чтобы он работал.

Я уверен, что есть и другие возможности, которые в основном одинаковы, вы не можете этого сделать.

...