【问题标题】:Why Doesn't PenAlignment.Inset Take Effect in User Control Drawing?为什么 PenAlignment.Inset 在用户控件绘图中不生效?
【发布时间】:2014-01-10 00:43:00
【问题描述】:

我做了一个自定义的可移动控件,但像素计算有问题。

控件大小为100、100,Padding和Margin均为0,0,0,0。

我认为从控件宽度(和高度)中减去笔宽两次就可以了,但是当我这样做时 DrawRectangle 中的底线和右线被部分或全部剪裁,具体取决于 pen.Width 的值和 size.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.Width 值,似乎 (90, 90) 点之外的整个图像都会被剪裁。

编辑:我刚刚发现,当 control.Location 设置为 (0, 0) 时,不会发生 unwatned 剪辑。

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

【问题讨论】:

  • 绘画相对于控件的客户区。因此,您必须使用var rec = new Rectangle(Point.Empty, size);

标签: c# winforms user-controls


【解决方案1】:

线宽可以是可变的,但整个粗线中心的精确 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);
}

【讨论】:

    【解决方案2】:

    通过引入另一个面板控件并将其添加到 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); 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-01
      • 2010-11-27
      • 2013-01-11
      • 2011-11-25
      • 1970-01-01
      • 2014-03-24
      • 2019-04-04
      相关资源
      最近更新 更多