如何在标签中创建图形对象
How to create a graphic object in a label
所以在我的项目中,我需要读取一个由“.”和“#”组成的.txt 文件。这个 .txt 文件是迷宫的地图。 # 是不可通过的对象,. 是应该能够收集的项目。
我已经设法在文本中进行解析并创建一个包含 Label
控件的 TableLayoutPanel
,其中包含 # 和 .'s。但是,我想将 . 替换为以单元格为中心的圆圈。
我该怎么做?
这是我的。
public class Import: TableLayoutPanel
{
public int zeilen, spalten;
TableLayoutPanel tlp = new TableLayoutPanel();
public TableLayoutPanel getData(string path)
{
StreamReader sr;
TableLayoutPanel tlp = new TableLayoutPanel();
tlp.Dock = DockStyle.Fill;
tlp.CellBorderStyle = 0;
if (File.Exists(path))
{
try
{
using (sr = new StreamReader(path))
{
spalten = Int32.Parse(sr.ReadLine().Trim());
zeilen = Int32.Parse(sr.ReadLine().Trim());
TableLayoutColumnStyleCollection Columns = tlp.ColumnStyles;
TableLayoutRowStyleCollection Rows = tlp.RowStyles;
foreach (ColumnStyle Column in Columns)
tlp.ColumnStyles.Add((new ColumnStyle(SizeType.Percent, 100.0F / Convert.ToSingle(spalten))));
foreach (RowStyle Row in Rows)
tlp.RowStyles.Add((new RowStyle(SizeType.Percent, 100.0F / Convert.ToSingle(zeilen))));
for (int i = 1; i <= zeilen; i++)
{
string line = sr.ReadLine();
for (int j = 1; j <= spalten; j++)
{
Label l = new Label();
tlp.Controls.Add(l, j-1, i-1);
l.Dock = DockStyle.Fill;
l.Text = line.Substring(j-1, 1);
l.Name = "l" + i.ToString() + "r" + (j).ToString();
if (line.Substring(j - 1, 1) == "#")
l.ForeColor = Color.Green;
if (line.Substring(j - 1, 1) == ".")
{
l.ForeColor = Color.Blue;
Graphics g = l.CreateGraphics();
g.DrawEllipse(new Pen(Color.Blue), l.Location.X, l.Location.Y, tlp.Width, tlp.Height);
}
}
}
return tlp;
}
}
catch(Exception e) { MessageBox.Show(e.Message); MessageBox.Show(e.StackTrace); return null; }
}
else
return null;
}
使用表单中的 Paint 事件:
https://msdn.microsoft.com/en-us/library/system.windows.forms.control.paint(v=vs.110).aspx
你可以在那里画任何东西。来自矩形、圆形、字符串等......
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
private readonly Pen greenPen = new Pen(Brushes.Green);
private readonly Pen redPen = new Pen(Brushes.Red);
private readonly Font testFont = new Font(FontFamily.GenericSansSerif, 10f);
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(redPen, 0f, 0f, 100f, 100f);
e.Graphics.DrawEllipse(greenPen, 10f, 10f, 200f, 200f);
e.Graphics.DrawString("Hello Graphics", testFont, Brushes.Blue, 30f, 30f);
}
}
}
创建 Label
时,您可以与其一起创建 Paint
事件,内联为 Lambda
:
Label l = new Label();
l.Name = "Label #" + (i * zeilen).ToString("00") + ":" + j.ToString("00");
l.Text = "ABCE";
l.Paint += (ss, ee) =>
{
// do your painting here:
using (LinearGradientBrush lgb =
new LinearGradientBrush(l.ClientRectangle, Color.Cyan, Color.DarkCyan, 0f))
ee.Graphics.FillRectangle(lgb, l.ClientRectangle);
ee.Graphics.DrawString(l.Text, Font, Brushes.Black, 1, 1);
};
您可以将 sender ss
转换为 Label
并访问其所有属性。请注意上面的 Lambda
将在需要绘制 Label
时被调用,即 每当您使 它或其容器之一无效或 每当系统需要刷新时。
它将始终使用 当前 数据,因此当您稍后更改文本时,它将使用新文本:
Label oneOfMyLabels = tlp.Controls["Label #03:02"] as Label; // pick or find the right one!
if (oneOfMyLabels != null)
{
oneOfMyLabels.Text = "New Text";
oneOfMyLabels.Invalidate(); // optional when change the text of a Label
}
请注意,您始终需要 存储控制 Paint
事件之外的绘画的数据,或者在 class 级别或以某种方式绑定到控件。
例如,当更改颜色时,您可以将它们存储在某处并使用这些值来创建渐变画笔,而不是对它们进行硬编码..
无论何时更改这些数据,都需要在 Label
上调用 Invalidate
。 Text
更改将为您做到这一点,但 other 数据需要 you 来触发重新绘制..!
另请注意,由于您 Labels 设置为 Dock.Fill
Cells 它们位于其中,您可以在那里绘制圆圈还有:
ee.Graphics.DrawEllipse(Pens.Blue, 0, 0, l.Width - 1, l.Height - 1);
当然我插入 LinearGradientBrush
只是为了好玩..
所以在我的项目中,我需要读取一个由“.”和“#”组成的.txt 文件。这个 .txt 文件是迷宫的地图。 # 是不可通过的对象,. 是应该能够收集的项目。
我已经设法在文本中进行解析并创建一个包含 Label
控件的 TableLayoutPanel
,其中包含 # 和 .'s。但是,我想将 . 替换为以单元格为中心的圆圈。
我该怎么做? 这是我的。
public class Import: TableLayoutPanel
{
public int zeilen, spalten;
TableLayoutPanel tlp = new TableLayoutPanel();
public TableLayoutPanel getData(string path)
{
StreamReader sr;
TableLayoutPanel tlp = new TableLayoutPanel();
tlp.Dock = DockStyle.Fill;
tlp.CellBorderStyle = 0;
if (File.Exists(path))
{
try
{
using (sr = new StreamReader(path))
{
spalten = Int32.Parse(sr.ReadLine().Trim());
zeilen = Int32.Parse(sr.ReadLine().Trim());
TableLayoutColumnStyleCollection Columns = tlp.ColumnStyles;
TableLayoutRowStyleCollection Rows = tlp.RowStyles;
foreach (ColumnStyle Column in Columns)
tlp.ColumnStyles.Add((new ColumnStyle(SizeType.Percent, 100.0F / Convert.ToSingle(spalten))));
foreach (RowStyle Row in Rows)
tlp.RowStyles.Add((new RowStyle(SizeType.Percent, 100.0F / Convert.ToSingle(zeilen))));
for (int i = 1; i <= zeilen; i++)
{
string line = sr.ReadLine();
for (int j = 1; j <= spalten; j++)
{
Label l = new Label();
tlp.Controls.Add(l, j-1, i-1);
l.Dock = DockStyle.Fill;
l.Text = line.Substring(j-1, 1);
l.Name = "l" + i.ToString() + "r" + (j).ToString();
if (line.Substring(j - 1, 1) == "#")
l.ForeColor = Color.Green;
if (line.Substring(j - 1, 1) == ".")
{
l.ForeColor = Color.Blue;
Graphics g = l.CreateGraphics();
g.DrawEllipse(new Pen(Color.Blue), l.Location.X, l.Location.Y, tlp.Width, tlp.Height);
}
}
}
return tlp;
}
}
catch(Exception e) { MessageBox.Show(e.Message); MessageBox.Show(e.StackTrace); return null; }
}
else
return null;
}
使用表单中的 Paint 事件:
https://msdn.microsoft.com/en-us/library/system.windows.forms.control.paint(v=vs.110).aspx
你可以在那里画任何东西。来自矩形、圆形、字符串等......
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
private readonly Pen greenPen = new Pen(Brushes.Green);
private readonly Pen redPen = new Pen(Brushes.Red);
private readonly Font testFont = new Font(FontFamily.GenericSansSerif, 10f);
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(redPen, 0f, 0f, 100f, 100f);
e.Graphics.DrawEllipse(greenPen, 10f, 10f, 200f, 200f);
e.Graphics.DrawString("Hello Graphics", testFont, Brushes.Blue, 30f, 30f);
}
}
}
创建 Label
时,您可以与其一起创建 Paint
事件,内联为 Lambda
:
Label l = new Label();
l.Name = "Label #" + (i * zeilen).ToString("00") + ":" + j.ToString("00");
l.Text = "ABCE";
l.Paint += (ss, ee) =>
{
// do your painting here:
using (LinearGradientBrush lgb =
new LinearGradientBrush(l.ClientRectangle, Color.Cyan, Color.DarkCyan, 0f))
ee.Graphics.FillRectangle(lgb, l.ClientRectangle);
ee.Graphics.DrawString(l.Text, Font, Brushes.Black, 1, 1);
};
您可以将 sender ss
转换为 Label
并访问其所有属性。请注意上面的 Lambda
将在需要绘制 Label
时被调用,即 每当您使 它或其容器之一无效或 每当系统需要刷新时。
它将始终使用 当前 数据,因此当您稍后更改文本时,它将使用新文本:
Label oneOfMyLabels = tlp.Controls["Label #03:02"] as Label; // pick or find the right one!
if (oneOfMyLabels != null)
{
oneOfMyLabels.Text = "New Text";
oneOfMyLabels.Invalidate(); // optional when change the text of a Label
}
请注意,您始终需要 存储控制 Paint
事件之外的绘画的数据,或者在 class 级别或以某种方式绑定到控件。
例如,当更改颜色时,您可以将它们存储在某处并使用这些值来创建渐变画笔,而不是对它们进行硬编码..
无论何时更改这些数据,都需要在 Label
上调用 Invalidate
。 Text
更改将为您做到这一点,但 other 数据需要 you 来触发重新绘制..!
另请注意,由于您 Labels 设置为 Dock.Fill
Cells 它们位于其中,您可以在那里绘制圆圈还有:
ee.Graphics.DrawEllipse(Pens.Blue, 0, 0, l.Width - 1, l.Height - 1);
当然我插入 LinearGradientBrush
只是为了好玩..