为什么PenAlignment.Inset不在用户控件绘图中生效?

时间:2013-12-21 05:16:07

标签: c# winforms user-controls

我制作了一个自定义可移动控件,并且在像素计算方面存在问题。

控件大小为100,100,填充和边距均为0,0,0,0。

我认为从控制宽度(和高度)减去两倍的笔宽度会有所作为,但是当我这样做时 DrawRectangle的Bottom和Right线被部分或全部剪裁,具体取决于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);
    }

无论pen的值是多少,看起来(90,90)点以外的整个图像都会被剪裁。选择宽度。

编辑:我刚刚发现当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);

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

通过引入另一个面板控件并将其添加到 real 容器来解决此问题。

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); 
}