Как добавить выноску в picturebox с помощью C #? - PullRequest
0 голосов
/ 08 марта 2019

Мне нужно добавить WedgeRectCallout выноску на картинку с помощью C #.

Есть ли способ сделать это?

Пожалуйста, обратитесь к изображению, используя ссылку ниже, чтобы узнать о выноске.

enter image description here

В текстовом документе я могу сделать то же самое, используя библиотеку Spire.Doc и написав следующий код:

 ShapeObject Shape1 = para1.AppendShape(30, 50, ShapeType.WedgeRectCallout);

1 Ответ

0 голосов
/ 08 марта 2019

Вот минимальный пример.Он создает Panel подкласс с вложенным TextBox.

Обратите внимание, что вы не можете добавить элементы управления к PictureBox в конструкторе.Вместо этого вы можете поместить его сверху и использовать функцию Nest для встраивания в PBox.

(я использую трюк, чтобы упростить рисование границы: поскольку сжатие GraphicsPath сложно иМне лень выписывать два из них, я дважды рисую границу и добавляю небольшое смещение. Эффект - эффект тени, который выглядит довольно неплохо для чита ..)

Вот класс вдействие:

enter image description here

А вот код класса:

class WedgeCallout : Panel
{
  public WedgeCallout()
  {
    tb = new TextBox();
    Controls.Add(tb);
  }

  TextBox tb = null;
  GraphicsPath gp = new GraphicsPath();

  protected override void OnLayout(LayoutEventArgs levent)
  {
    tb.Size = new Size(Width - 10, (int)(Height * 0.66));
    tb.Location = new Point(5, 5);
    tb.BackColor = BackColor;
    tb.ForeColor = ForeColor ;
    tb.BorderStyle = BorderStyle.None;
    tb.Text = "Hiho";
    tb.Multiline = true;
    tb.TextAlign = HorizontalAlignment.Center;
    tb.Font = Font;
    SetRegion();
    base.OnLayout(levent);
  }

  protected override void OnBackColorChanged(EventArgs e)
  {
    base.OnBackColorChanged(e);
    if (BackColor != Color.Transparent) 
        tb.BackColor = BackColor;
  }

  protected override void OnPaint(PaintEventArgs e)
  {
    base.OnPaint(e);
    if (Tag == null) return;

    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    using(SolidBrush brush = new SolidBrush(tb.BackColor))
        e.Graphics.FillPath(brush, (GraphicsPath)Tag);
    using (Pen pen = new Pen(Color.DarkGray, 2f))
        e.Graphics.DrawPath(pen, (GraphicsPath)Tag);
    e.Graphics.TranslateTransform(-1, -1);
    using (Pen pen = new Pen(ForeColor, 2f))
        e.Graphics.DrawPath(pen, (GraphicsPath)Tag);
  }

  void SetRegion()
  {
    Rectangle r = ClientRectangle;
    int h = (int)(r.Height * 0.75f);
    if (gp != null) gp.Dispose();
    gp = new GraphicsPath();
    gp.AddPolygon(new PointF[]{   new Point(0,0),
        new Point(r.Width-1, 0),  new Point(r.Width-1, h),
        new PointF(50, h) ,       new Point(0, r.Height-1),
        new PointF(20, h),        new PointF(0, h)});

    Region = new Region(gp);
    Tag = gp;
  }
}

Вы можете установить цвета и шрифт в конструкторе..

И функция Nest:

void Nest(Control child, Control parent)
{
    Point p0 = parent.PointToScreen(Point.Empty);
    Point p1 = child.PointToScreen(Point.Empty);
    child.Location = new Point(p1.X - p0.X, p1.Y - p0.Y);
    child.Parent = parent;
}

Вызывается из формы, в которой находятся элементы управления: Nest(wedgeCallout1, pictureBox1);

Обратите внимание, что для сохранения в выноскус pbox в одном изображении вам необходимо

  • Nest выноска в PBox
  • Использование pbox.DrawToBitmap
  • Временно установить цвет фонак прозрачному

Пример:

private void saveBtn_Click(object sender, EventArgs e)
{
    Size sz = pictureBox1.ClientSize;
    using (Bitmap bmp = new Bitmap(sz.Width, sz.Height))
    {
        Color old = wedgeCallout1.BackColor;
        wedgeCallout1.BackColor = Color.Transparent;
        pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
        bmp.Save(filename, ImageFormat.Png);
        wedgeCallout1.BackColor = old;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...