2013-12-21 6 views
0

Я сделал собственный движимый элемент управления и имею проблему с вычислением пикселей.Почему PenAlignment.Inset не влияет на пользовательский чертеж?

Размер управления 100, 100, а заполнение и маржа - 0,0,0,0.

Я думал, что вычитание ширины пера в два раза из ширины (и высоты) будет выполняться, но когда я делаю Нижняя и правая линии от DrawRectangle обрезаются частично или полностью, в зависимости от значений pen.Width и коэффициентов уменьшения размера. Ширина size.Height

protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     var pen = new Pen(Color.Black); 
     pen.Width = 16; 
     pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset; 
     var brush = Brushes.Aquamarine; 
     var size = this.Size; 
     size.Width -= (int)(pen.Width * 2); 
     size.Height -= (int)(pen.Width * 2); 
     var rec = new Rectangle(this.Location, this.Size); 
     e.Graphics.FillRectangle(brush, rec); 
     e.Graphics.DrawRectangle(pen, rec); 
    } 

Похоже всего изображения за пределами (90, 90) точка не усекается независимо от того, какое значение выбрано pen.Width.

РЕДАКТИРОВАТЬ: Я только что обнаружил, что неуправляемое обрезание не происходит, когда control.Location установлен (0, 0).

public partial class Form1 : Form 
{ 
    MTC control; 
    public Form1() 
    { 
     InitializeComponent(); 

     control = new MTC(); 
     control.Parent = panel1; 
     control.Width = 100; control.Height = 200; 
     //control.Left = 100; control.Top = 100; 
     control.Location = new Point(0, 0); 
     panel1.Controls.Add(control); 
+0

Окраска относится к клиентской зоне управления. Поэтому вы должны использовать 'var rec = new Rectangle (Point.Empty, size);' –

ответ

0

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

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 

    var pen = new Pen(Color.Black); 
    pen.Width = 16; 
    pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset; 
    var brush = Brushes.Aquamarine; 
    var halfPenWidth = pen.Width/2; 
    var rec = new RectangleF(Location, Size); 
    rec.Width -= pen.Width; 
    rec.Height -= pen.Width; 
    rec.X += halfPenWidth; 
    rec.Y += halfPenWidth; 
    e.Graphics.FillRectangle(brush, rec); 
    //Graphics.DrawRectangle does not support RectangleF directly 
    e.Graphics.DrawRectangle(pen, rec.Left, rec.Top, rec.Width, rec.Height); 
} 
0

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

public class Movable : Control 
{ 
    public Panel ContainerPanel { get; set; }  
    public Movable(Point location, Size size) : base() 
    { 
     var pan = new Panel(); 
     pan.Margin = new Padding(0); 
     pan.Padding = new Padding(0); 
     pan.Location = location; 
     pan.Size = size; 
     this.ContainerPanel = pan; 
     this.Location = new Point(0, 0); 
     this.Size = size; 
     pan.Controls.Add(this); 
     pan.Height = size.Height; // Resize again after addition of 'content' 
     this.movable = isMovable; 
    } 
    // codes for OnMouseDown, OnMouseUp, OnMouseMove, ... 
} 

public class MovableTest : Movable 
{ 
    public MovableTest(Point location, Size size) 
     : base(location, size) { } 
    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) 
    { 
     base.OnPaint(e); 
     // user drawing code comes here 
    } 
} 

public partial class Form1 : Form 
{ 
    MovableTest ctrl2; 
    ctrl2 = new MovableTest(new Point(75, 50), new Size(100, 100)); 

    // add .ContainerPanel, NOT ctrl2 itself! 
    this.Controls.Add(ctrl2.ContainerPanel); 
} 
Смежные вопросы