C#绘制大型图表(二进制树)WinForms

本文关键字:二进制 WinForms 绘制 型图 | 更新日期: 2023-09-27 18:24:47

我正在尝试绘制它的二叉树表示,但没有成功

我尝试过在绑定到PictureBox的Image上使用GDI绘制,但最终我的Image变得太大了,我无法调整它的大小,然后我选择了Panel,并尝试直接在它上绘制-效果要好得多,但是:

我从控件的中上角开始向下绘制,不幸的是,在某个时候,我的绘图会出现-x和x,比控件的宽度大(需要提醒的是面板)。首先,左边的绘图似乎没有绘制出来(我认为这是因为它们超出了面板的范围),其次,尽管我的面板将AutoSize属性设置为True,但它不会调整大小。

我将感谢任何关于我应该如何实现它的想法。

C#绘制大型图表(二进制树)WinForms

我想@TaW已经说过了,不幸的是,这并不是一个答案。面板将处理滚动,PictureBox将包含图像。

  • 您需要将AutoScroll设置为TruePanel
  • 此面板内需要PictureBoxSizeMode设置为AutoSize
  • 您可以根据Bitmap进行所有绘制。完成后,将此位图附加到PictureBox

绘图示例:

Bitmap bmp = new Bitmap(1000, 1000);
using (Graphics g = Graphics.FromImage(bmp))
{
    g.FillRectangle(Brushes.Green, 0, 0, 10, 10);
    g.DrawEllipse(Pens.Black, 10, 10, 900, 900);
}
pictureBox1.Image = bmp;

编辑

所以问题出在尺寸上。您可以选择仅光栅化可见的零件。速度可能会有问题,但内存占用将是最小的。简单的概念证明:

System.Windows.Forms.TableLayoutPanel tableLayoutPanel1 = null;
private void Form1_Load(object sender, EventArgs e)
{
    this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
    // 
    // tableLayoutPanel1
    // 
    this.tableLayoutPanel1.AutoScroll = true;
    this.tableLayoutPanel1.ColumnCount = 1;
    this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 2000));
    this.tableLayoutPanel1.Location = new System.Drawing.Point(25, 25);
    this.tableLayoutPanel1.Name = "tableLayoutPanel1";
    this.tableLayoutPanel1.RowCount = 1;
    this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 1000));
    this.tableLayoutPanel1.Size = new System.Drawing.Size(this.Width - 50, this.Height - 80);
    this.tableLayoutPanel1.TabIndex = 21;
    this.tableLayoutPanel1.Paint += new System.Windows.Forms.PaintEventHandler(this.tableLayoutPanel1_Paint);
    this.tableLayoutPanel1.Anchor = AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
    this.Controls.Add(this.tableLayoutPanel1);
    this.tableLayoutPanel1.BringToFront();
}
private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
{
    float virtualWidth = tableLayoutPanel1.ColumnStyles[0].Width;
    if (virtualWidth < 40000) //You can resize the area any time
    {
        tableLayoutPanel1.ColumnStyles[0].Width = 40000;
        tableLayoutPanel1.RowStyles[0].Height = 20000;
        tableLayoutPanel1.Invalidate();
        return;
    }
    e.Graphics.TranslateTransform(
        virtualWidth / 2 - tableLayoutPanel1.HorizontalScroll.Value,
        -tableLayoutPanel1.VerticalScroll.Value);
    int size = 50;
    for (int i = 0; i < 200; ++i)
    {
        for (int j = -i; j <= i; j++)
        {
            e.Graphics.DrawEllipse(Pens.Black, j * size * 2, i * size * 2, size, size);
        }
    }
}

我选择了一行一列的tableLayoutPanel1,它可以滚动并让我设置工作区域。tableLayoutPanel1可以在设计器中制作,我决定动态构建它,只为了显示完整的工作示例(只需要分配Form1_Load事件)。您可以通过跳过不可见的部分来加快速度,比如"i"变量的下限和上限。您还可以将较大的部分光栅化为位图,并在其边界内从该位图进行复制。