【问题标题】:How to flip alignment of drawn content in a panel如何翻转面板中绘制内容的对齐方式
【发布时间】:2014-11-11 04:06:01
【问题描述】:

我正在使用两个面板沿图片框的两侧(顶部和左侧)绘制标尺。它可以工作,但现在我的要求是翻转标尺的方向,使线条从图片框开始,文本(数字)在顶部。我该怎么做?

我的代码如下:

 private void panel2_Paint(object sender, PaintEventArgs e)//left Panel
    {
        Graphics g = e.Graphics;
        g.PageUnit = GraphicsUnit.Millimeter;
        int step = 1;
        int length = panelleft.Height / 3;
        int small = 5;
        int big = 10;
        int number = 10;
        int scale = 10;
        float stroke = 2.5f;
        for (int i = 0; i < length; i += step)
        {
            float d = 1;
            if (i % small == 0)
            {
                if (i % big == 0)
                {
                    d = 3;
                }
                else
                {
                    d = 2;
                }
            }
            g.DrawLine(this.pen, 0f, i,d * stroke, i);             
            if ((i % number) == 0)
            {
                string text = (i / scale).ToString();
                SizeF size = g.MeasureString(text, this.Font, length, this.format);
                g.DrawString(text, this.Font, Brushes.Black,d * stroke, i - size.Width-1 / 2 , this.format);                  
            }
        }
    }

 private void panel3_Paint(object sender, PaintEventArgs e)// top panel
    {
        Graphics g = e.Graphics;
        g.PageUnit = GraphicsUnit.Millimeter;
        int step = 1;//incremnent
        int length = paneltop.Width / 3; //panelinte  widthinte pakuthi mathi bcs namml oru point gap vittanu line varakunnath     
        int small = 5;//cheriya vark ulla length
        int big = 10;//valiya vark ulla length
        int number = 10;//units 1cm=10 units           
        float stroke = 2.5f;

        for (int i = 0; i < length; i += step)
        {
            float d = 1;
            if (i % small == 0)//cheriya line 
            {
                if (i % big == 0)//valiya line
                {
                    d = 3; //varyude length
                }
                else
                {
                    d = 2;//varyude length
                }
            }
            g.DrawLine(this.pen, i, 0f, i, d * stroke);//lines varakunnu
            if ((i % number) == 0)//0,1,,2
            {
                string text = (i / number).ToString();//1,2,3 ennu ezhuthan
                SizeF size = g.MeasureString(text, this.Font, length, this.format);//ezhuthuna stringnte length ariyan// one digit length 1.618635,2 digit length3.23727
                g.DrawString(text, this.Font, Brushes.Black, i - size.Width / 2, d * stroke, this.format);//Y constant ayirikum (d* stroke) ennu koduthath line kazhinju string varan anu alenkil overlapp cheyum 
                //                                            (        X       )  (     Y   )
            }
        }

    }

我还想显示一条水平和垂直线,当用户将鼠标移到图像上时,它们必须指向标尺。

所需的输出样本:

【问题讨论】:

  • 什么是flip?我无法想象最终结果,您能否提供一份预期结果的草稿(考虑在编辑时将问题标记为winforms)?关于鼠标,您必须处理鼠标事件:MouseMoveMouseEnterMouseLeave 为面板调用 Invalidate() 并设置标志何时绘制线条,而在 Paint 中只需 getting mouse position 和绘制线条。

标签: c# winforms graphics drawing


【解决方案1】:

由于您已将Graphics 设置为mm,因此您需要计算控件像素大小的转换因子:

float dpi = e.Graphics.DpiX;
float factor = 25.4f / dpi;

有了这个,您可以像这样简单地调整您的 DrawStringDrawLine 调用:

panel2_Paint:

   float w = panelleft.Width * factor;

   g.DrawLine(this.pen, w - d * stroke, i, w, i);

   g.DrawString(text, this.Font, Brushes.Black, 
                w - d * stroke - size.Width, i - size.Width - 1 / 2, this.format);

panel3_Paint

  float h = paneltop.Height * factor;

  g.DrawLine(this.pen, i, h - d * stroke, i, h);

  g.DrawString(text, this.Font, Brushes.Black, 
               i - size.Width / 2, h - d * stroke - size.Height, this.format);

要显示光标线,您可以使用:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    Point mp = pictureBox1.PointToClient(Cursor.Position);

    if (e.ClipRectangle.Contains(mp))
    {
        e.Graphics.DrawLine(Pens.Red, 0, mp.Y, e.ClipRectangle.Width, mp.Y);
        e.Graphics.DrawLine(Pens.Red, mp.X, 0, mp.X, e.ClipRectangle.Height);
    }
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    pictureBox1.Invalidate();
}

这是使用一些假设的结果:

panelleft = panel2;
paneltop = panel3;
format = StringFormat.GenericTypographic;
pen = new Pen(Color.Black, 0.25f);

理论上你应该分别使用dpiX dpiY来得到两个因子。

【讨论】:

  • 等我检查并通知
  • @TaW 非常感谢.. 为您的努力.. 还有一个帮助,我需要在文本框中获取 X 和 Y 位置。我想使用哪个事件
  • 没问题;我喜欢你的问题 ;-) - 对于 mm,你可以将这样的代码放入 PictureBoxMouseMove 中:somecontrolX.Text = ( e.X * factor / 10).ToString("##0.0"); 当然,对于不需要计算的像素。 - 但是您需要将float factor声明(不是分配)移出事件并移至班级级别!
  • @TaW 我们不能使用pictureBox1_Paint 事件。我得到的结果是这有什么缺点。
  • @TaW 如果假设我想从右侧和下方删除光标线,我应该怎么做。我需要_|像这样。
【解决方案2】:

对于第一个,您希望将 DrawLine 和 DrawString 调用更改为与当前的相反。

在 Panel3 中绘制:

g.DrawLine(this.pen, i, 0f, i, d * stroke);//lines varakunnu

这会画一条从 (i, 0) 到 (i, d*stroke) 的线。我们想反转这条线,所以我们会这样做:

g.DrawLine(this.pen, i, panel3.Height, i, (panel3.Height - d * stroke));//lines varakunnu

我们也想调整标签,所以我们会改变这个:

g.DrawString(text, this.Font, Brushes.Black, i - size.Width / 2, d * stroke, this.format);

g.DrawString(text, this.Font, Brushes.Black, i - size.Width / 2, (panel3.Height - d * stroke - size.Height), this.format);

g.DrawString(text, this.Font, Brushes.Black, i - size.Width / 2, (panel3.Height - d * stroke), this.format);

我不确定您是否需要补偿 size.Height,因为我无法测试您的代码。

【讨论】:

  • g.DrawLine(this.pen, i, panel3.Height, i, (panel3.Height - d * stroke));它没有画线。我如何将代码发送给您。 SO中有什么选择吗
猜你喜欢
  • 1970-01-01
  • 2012-07-22
  • 1970-01-01
  • 1970-01-01
  • 2014-02-05
  • 2015-09-17
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多