私は二分木の内容を視覚的に出力するプログラムに取り組んできました(私が自分で書いたクラスによって順番に表されます)。このプログラムに含めたい最後の機能は、ツリーのポストオーダー、インオーダー、およびプレオーダーの構築のアニメーションです。
これは私が思っていたよりもはるかに難しいことが証明されました。元の描画方法は次のとおりです。
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;
}
私の当初のアイデアは、最初の2つのif句のそれぞれにThread.Sleep(1000)を入れることでした。実際に必要なのは、ノードを描画する前にプログラムの実行を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();
}
};
}
}