C# 绘制没有重叠文本的多个字符串

C# 绘制没有重叠文本的多个字符串,c#,.net,winforms,system.drawing,C#,.net,Winforms,System.drawing,我想在C#中的一个矩形上打印多个不同的字符串。 我的问题是打印字符串时字符串总是重叠。 我无法打印整个字符串,因为每行都有另一种字体。 RectangleF[] rectangles = { new RectangleF(650.8188976377953F, 57.48031496062993F, 275.59055118110234F, 334.6456692913386F) }; StringFormat stringFormat = new StringFormat();

我想在C#中的一个矩形上打印多个不同的字符串。

我的问题是打印字符串时字符串总是重叠。
我无法打印整个字符串,因为每行都有另一种字体。

RectangleF[] rectangles = { 
    new RectangleF(650.8188976377953F, 57.48031496062993F, 275.59055118110234F, 334.6456692913386F) 
};

StringFormat stringFormat = new StringFormat();
stringFormat.Alignment = StringAlignment.Center;
stringFormat.LineAlignment = StringAlignment.Center;        

e.Graphics.DrawRectangles(blackPen, rectangles);
e.Graphics.DrawString("test1", headLine, black,rectangles[0],stringFormat);
e.Graphics.DrawString("test2", subLines, black, rectangles[0], stringFormat);

我如何绘制它们,使它们不重叠,并将它们放置在我想要的任何地方,而不使用坐标?

您可以使用

Graphics.MeasureString("test1", StringFont)

然后,您可以从返回的大小点扩展矩形目标。

字符串重叠,因为您有一个绘图区域(
矩形[0]
),并且所有字符串都在该区域中绘制,没有关于其位置的任何进一步指示。
由于设置为
StringAlignment.Center
,因此所有文本都在由
矩形[0]
定义的区域中心绘制

要在绘图区域内将一系列字符串居中,可以将字符串序列加上分隔字符串的空间想象为一个矩形。
要将此矩形(绘图区域)居中放置在容器对象内,可以将此部分之间的关系定义为:

Drawing Area Height = (Text Height * Number of Strings) + (Interline * (Number of Strings - 1))

Blank Area Height = (Container Height - Drawing Area Height)
因此,容器内的非原始绘图区域的中心位置为:

Container Top + (Blank Area Height / 2)
现在我们知道从哪里开始画文本线了。所有其他字符串位置都相对于已计算的绘图区域(因为它们都是此度量的一部分)。
这样,您就不需要在容器中手动定位字符串。


为了定义不同的字符串及其相关属性(文本、字体、字体类型、文本高度、文本颜色),我使用了
列表

List<Tuple<string, string, FontStyle, float, Brush>> DrawingStrings = new List<Tuple<string, string, FontStyle, float, Brush>>()
{
    new Tuple<string, string, FontStyle, float, Brush>("Text", "Font", FontStyle, Height, Brush),
    //(...)
}
容器矩形(
rectangles[0]
)内的文本位置是自动计算的。
因此,您可以向列表中添加更多字符串,它们将被相应地定位。

e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

List<RectangleF> rectangles = new List<RectangleF>() {
    new RectangleF(5.8188976377953F, 5.48031496062993F, 170.59055118110234F, 170.6456692913386F)
};

List<Tuple<string, string, FontStyle, float, Brush>> DrawingStrings = new List<Tuple<string, string, FontStyle, float, Brush>>()
{
    new Tuple<string, string, FontStyle, float, Brush>("A Graphics", "Arial", FontStyle.Regular, 20F, Brushes.LightGreen),
    new Tuple<string, string, FontStyle, float, Brush>("String Drawing", "Segoe UI", FontStyle.Regular, 17F, Brushes.Orange),
    new Tuple<string, string, FontStyle, float, Brush>("Example", "Calibri", FontStyle.Regular, 22F, Brushes.SteelBlue)
};

float Interline = 12.0F;
float TextHeigh = - Interline + (DrawingStrings.Select(tp => tp.Item4 + Interline).Sum());
float TextPosition = ((rectangles[0].Height - TextHeigh + Interline) / 2);

StringFormat TextFormat = new StringFormat() {
    Alignment = StringAlignment.Center,
    LineAlignment = StringAlignment.Center,
    FormatFlags = StringFormatFlags.NoClip,
    Trimming = StringTrimming.EllipsisWord
};

foreach (Tuple<string, string, FontStyle, float, Brush> item in DrawingStrings)
{
    rectangles.Add(new RectangleF()
    {
        Width = rectangles[0].Width,
        Location = new PointF(rectangles[0].X, TextPosition),
        Height = item.Item4
    });
    TextPosition += item.Item4 + Interline;
};
//e.Graphics.DrawRectangles(Pens.White, rectangles.ToArray());

int RectArea = 0;
foreach (Tuple<string, string, FontStyle, float, Brush> item in DrawingStrings)
{
    RectArea += 1;
    using (Font font = new Font(item.Item2, item.Item4, item.Item3, GraphicsUnit.Pixel))
        e.Graphics.DrawString(item.Item1, font, item.Item5, rectangles[RectArea], TextFormat);
};

这不是我需要的答案,但你让我走上了正确的道路。无论如何谢谢你@Felix如果你需要一些不同的东西,在你的问题中添加一些细节,并进一步解释。我将在答案中添加一个更新(如果可行的话——将字符串放在没有坐标的任何地方都是不可能的)。您尚未说明您的问题是否与
WinForms
相关。在这种情况下,设置正确的标签是很重要的。正如我所说,你帮助我回答了你的问题,我解决了我的问题。谢谢你:)不,是WinForms:)
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

List<RectangleF> rectangles = new List<RectangleF>() {
    new RectangleF(5.8188976377953F, 5.48031496062993F, 170.59055118110234F, 170.6456692913386F)
};

List<Tuple<string, string, FontStyle, float, Brush>> DrawingStrings = new List<Tuple<string, string, FontStyle, float, Brush>>()
{
    new Tuple<string, string, FontStyle, float, Brush>("A Graphics", "Arial", FontStyle.Regular, 20F, Brushes.LightGreen),
    new Tuple<string, string, FontStyle, float, Brush>("String Drawing", "Segoe UI", FontStyle.Regular, 17F, Brushes.Orange),
    new Tuple<string, string, FontStyle, float, Brush>("Example", "Calibri", FontStyle.Regular, 22F, Brushes.SteelBlue)
};

float Interline = 12.0F;
float TextHeigh = - Interline + (DrawingStrings.Select(tp => tp.Item4 + Interline).Sum());
float TextPosition = ((rectangles[0].Height - TextHeigh + Interline) / 2);

StringFormat TextFormat = new StringFormat() {
    Alignment = StringAlignment.Center,
    LineAlignment = StringAlignment.Center,
    FormatFlags = StringFormatFlags.NoClip,
    Trimming = StringTrimming.EllipsisWord
};

foreach (Tuple<string, string, FontStyle, float, Brush> item in DrawingStrings)
{
    rectangles.Add(new RectangleF()
    {
        Width = rectangles[0].Width,
        Location = new PointF(rectangles[0].X, TextPosition),
        Height = item.Item4
    });
    TextPosition += item.Item4 + Interline;
};
//e.Graphics.DrawRectangles(Pens.White, rectangles.ToArray());

int RectArea = 0;
foreach (Tuple<string, string, FontStyle, float, Brush> item in DrawingStrings)
{
    RectArea += 1;
    using (Font font = new Font(item.Item2, item.Item4, item.Item3, GraphicsUnit.Pixel))
        e.Graphics.DrawString(item.Item1, font, item.Item5, rectangles[RectArea], TextFormat);
};
     Interline 12.0F          Interline 16.0F