我一直在开发一个程序,该程序可以直观地输出二叉树的内容(依次由我自己编写的类表示)。我想在这个程序中包含的最后一个功能是树的后序、中序和前序构造的动画。
事实证明,这比我想象的更具挑战性。这是原始的绘制方法:
private void DrawNode(int x, int y, BinaryTreeNode<T> node, int nodeLevel, int maxDepth, int connectX = -1, int connectY = -1, )
{
//calculate distance between the node's children
int distance = CalculateDistance(nodeLevel, maxDepth);
//draw the node at the specified coordinate
node.Draw(x, y, this.device);
if (node.Left != null)
{
DrawNode(x - distance / 2, y + 50, node.Left, nodeLevel + 1, maxDepth, x, y, node);
}
if (node.Right != null)
{
DrawNode(x + distance / 2, y + 50, node.Right, nodeLevel + 1, maxDepth, x, y, node);
}
//connect the node to its parent
if ((connectX != -1) && (connectY != -1))
{
node.Connect(connectX, connectY, device);
}
this.display.Image = surface;
}
我最初的想法是简单地将 Thread.Sleep(1000) 放在前两个 if 子句中——我真正需要做的就是在每次绘制节点之前暂停程序的执行 1 秒钟。
我意识到 Sleep 方法阻塞了绘图代码的执行,所以我放弃了那个方法。然后我尝试使用 Timers,但在处理树时发现它非常困难。
我的目标是简单地找到一种方法来暂停程序执行,而不会破坏 GUI 的响应能力,也不会使代码过于复杂。
任何帮助,将不胜感激 :)。
编辑:一些可能相关的信息:程序在 Winforms 上运行,所有图形都通过 GDI+ 处理。如果您需要任何其他信息,请询问:)
编辑:对于 SLaks,
//draw the node's children
if (drawChildren)
{
if (node.Left != null)
{
if (this.timer2.Enabled)
{
this.timer2.Stop();
}
if (!this.timer1.Enabled)
{
this.timer1.Start();
}
this.count1++;
this.timer1.Tick += (object source, EventArgs e) =>
{
this.count1--;
DrawNode(x - distance / 2, y + 50, node.Left, nodeLevel + 1, maxDepth, x, y, node);
if (this.count1 == 0)
{
this.timer1.Stop();
}
};
}
else
{
this.timer1.Stop();
this.timer2.Start();
}
if (node.Right != null)
{
this.count2++;
this.timer2.Tick += (object source, EventArgs e) =>
{
this.count2--;
DrawNode(x + distance / 2, y + 50, node.Right, nodeLevel + 1, maxDepth, x, y, node);
if (this.count2 == 0)
{
this.timer2.Stop();
}
};
}
}