【问题标题】:How to create a graphic object in a label如何在标签中创建图形对象
【发布时间】:2016-07-03 11:52:42
【问题描述】:

所以在我的项目中,我需要读取一个由“.”和“#”组成的 .txt 文件。这个 .txt 文件是迷宫的地图。 # 是不可通过的对象,而 . 是应该能够被收集的项目。

我已经设法解析文本并创建一个包含Label 控件的TableLayoutPanel,其中包含# 和.。但是,我想将 . 替换为以单元格为中心的圆圈。

我该怎么做? 这是我所拥有的。

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 事件中完成,但是我强烈建议您使用 WPF 等图形更“友好”的环境而不是 WinForms
  • 遗憾的是,在这种情况下我需要使用 winforms(任务说我必须这样做)。我尝试使用图形事件,但我不知道如何获取 .'s 的特定单元格的位置。你知道我怎样才能完成这项工作吗?

标签: c# winforms graphics io gdi+


【解决方案1】:

创建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 并访问其所有属性。请注意,每当需要绘制 Label 时,即无论何时它或其容器之一或系统需要时,都会调用上述 Lambda刷新它。

它将始终使用当前数据,因此当您稍后更改文本时,它将使用新文本:

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 事件外部 存储控制绘画的数据

例如,在更改颜色时,您会将它们存储在某个地方并使用这些值来创建渐变画笔,而不是对它们进行硬编码..

每当您更改这些数据时,您都需要在Label 上致电InvalidateText 更改将为您执行此操作,但其他数据需要触发重新绘制..!

另请注意,由于您的标签设置为Dock.Fill它们所在的单元格,您也可以在那里绘制圆圈:

 ee.Graphics.DrawEllipse(Pens.Blue, 0, 0, l.Width - 1, l.Height - 1);

当然,我插入 LinearGradientBrush 只是为了好玩..

【讨论】:

    【解决方案2】:

    使用表单中的 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);
        }
      }
    }
    

    【讨论】:

    • 我已经尝试过使用绘画事件,但我不知道如何获取“。”的位置。我的绘画方法中的单元格。
    • 创建自己的UserControl并在那里使用Paint更容易,而不是使用TableLayoutPanel和Label然后找到“。”。
    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多