我想在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);
如何绘制它们,以使它们不重叠并将其放置在我想要的任何位置而无需使用坐标?
答案 0 :(得分:3)
您的字符串重叠是因为您有一个绘制区域(rectangles[0]
),所有字符串都绘制在该区域中,而没有关于它们位置的任何进一步说明。
由于StringFormat.LineAlignment
设置为StringAlignment.Center
,因此所有文本都绘制在rectangles[0]
定义的区域的中心。
要在绘画区域内居中放置一系列字符串,您可以想象一下您的字符串序列,加上将它们分开的空间,以矩形显示。
要将这个Rectangle(绘图区域)居中放置在Container对象中,可以将这些零件之间的关系定义为:
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)
现在,我们知道从哪里开始绘制文本行了。所有其他字符串位置都相对于已经计算的“绘图区域”(因为它们都是该度量的一部分)。
这样,您无需手动将字符串放置在Container中。
要定义不同的字符串及其相对属性(文本,字体,字体类型,文本高度,文本颜色),我使用了List<Tuple>
:
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),
//(...)
}
但是您也可以使用List<[Class]>
或您认为合适的其他任何适当的对象。
文本行由中间行分隔。
您可以修改此值并指定其他行距:
float Interline = 12.0F;
“容器”矩形(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);
};
这是您在代码中看到的List<Tuple>
的结果,以及如果添加另一行Text会发生的情况:
如果取消注释此行:e.Graphics.DrawRectangles(Pens.White, rectangles.ToArray());
,则可以看到如何使用不同的行间值来调整矩形的大小:
Interline 12.0F Interline 16.0F
答案 1 :(得分:0)
您可以通过以下方式获取绘制的字符串大小:
Graphics.MeasureString("test1", StringFont)
然后,您可以从返回的大小点扩展矩形目标。