C# 绘制没有重叠文本的多个字符串
我想在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();
我的问题是打印字符串时字符串总是重叠。
我无法打印整个字符串,因为每行都有另一种字体。
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