首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用树和线程执行C#撤消/重做

使用树和线程执行C#撤消/重做
EN

Stack Overflow用户
提问于 2012-03-21 18:36:01
回答 1查看 274关注 0票数 1

我已经搜索了几个小时,还没有找到任何类似于这个问题的东西,尽管我确定它以前肯定已经做过了:

用户首先输入数字和+/-符号的组合。例如:5+ (7-(4+1)-3) + 11。我有一个类Add和一个类Subtract,程序根据输入构建这两个类的树。所以在这个例子中,树看起来像这样:

代码语言:javascript
运行
复制
Add: 5
     Subtract: 7
     11        Add: 4
               3    1

现在,每个类都有一个递归StepEvaluate方法,该方法首先将整个总和打印到控制台。因此,对于上一个示例的减法子树,该对象将打印"7 - (4+1) - 3“。然后,它将列出树的每个节点,并要求用户单击一个分支以对最初为0的运行总数进行加/减。它最终会在最后打印出答案。因此,如果我们采用5+ (7-3) + 11,则控制台的输出将为:

代码语言:javascript
运行
复制
5 + (7-3) + 11
We are going to add to the total with each choice.
The current total is 0.
Choose from the following:
5
+
7-3
+
11
You chose: 11
The current total is 11.
Choose from the following:
5
+
7-3
You chose: 7-3
    7 - 3
    We are going to subtract from the total with each choice.
    The current total is 0.
    Choose from the following:
    7
    -
    3
    You chose: -3
    The current total is -3.
    The only remaining choice is 7.
    The current total is 4.
    So the answer is 4.
The current total is 15.
The only remaining choice is 5.
The current total is 20.
So the answer is 20.

现在我的控制台是一个文本框。在表单构造函数中,创建了一个新线程Eval,用于计算和输出上述结果。用户每次按下按钮,它都会恢复线程Eval并暂停当前线程。然后,Eval计算出下一个要输出的字符串(使用上面的递归类),将该字符串写入静态变量,恢复主线程的执行,并暂停Eval的执行。然后,主线程读取这些静态变量并将其输出到textbox (生产者-消费者)。在两次单击按钮之间,用户的输入被写入静态变量,这样一旦恢复,Eval就可以读取这些变量。

我想在表单上有另一个按钮,这将返回一行。如果删除了"You chose“这一行,则用户可以更改他的选择,因此下一个输出可以是"You chose”。

我已经阅读了memento和command模式,并了解了基于状态和基于操作的撤消/重做。然而,我不知道如何使用上面的递归和生产者/消费者线程来实现这一点。我真正需要的是一种方法,让Eval go的执行点回到一行。但我很确定我不能这么做。

如果你想要加法和减法的代码,你可以这样做:

代码语言:javascript
运行
复制
class Add : MathsOperation
{
    public List<MathsOperation> Children;

    private int total;

    public override void StepEvaluate()
    {
        MathsOperation currentEvaluation;
        writeToConsole(this.ToString());

        List<MathsOperation> toBeEvaluated = new List<MathsOperation>(Children);

        writeToConsole("We are going to add to the total with each choice."); 


        while (toBeEvaluated.Count > 1)
        {
            writeToConsole("The current total is " + total + ".");
            writeToConsole("Please choose from the following:");
            string choices = "";
            foreach (MathsOperation child in toBeEvaluated)
            {
                choices += Environment.NewLine  + child.ToString();
                if (child != Children.Last())
                    choices += Environment.NewLine + "+";
            }
            writeToConsole(choices);

            currentEvaluation = read();

            if (currentEvaluation is Number)
            {
                //add to the total and write output
            }
            else
            {
                currentEvaluation.StepEvaluate();
                //add the static variable Result to the total and write output
            }

            toBeEvaluated.Remove(currentEvaluation);
        }

        currentEvaluation = toBeEvaluated.First();
        writeToConsole("The only remaining choice is " + currentEvaluation.ToString());

        if (currentEvaluation is Number)
        {
            //add to the total and write output
        }
        else
        {
            currentEvaluation.StepEvaluate();
            //add the static variable Result to the total and write output
        }

        toBeEvaluated.Remove(currentEvaluation);

        writeToConsole("So the answer is " + total.ToString());

        //write total to static variable Result

    }

    private void writeToConsole(string txt)
    {
        //Write to static variable, resume main thread and pause this one
    }
    private MathsOperation read()
    {
        //read the static variable. I have replaced this with return new for simplicity
        return new MathsOperation();
    }
}

如果你有任何想法,我将非常乐意接受。

非常感谢您的帮助。

EN

回答 1

Stack Overflow用户

发布于 2012-06-14 14:33:58

我会使用这样的解决方案:使用undo/redo框架。我在theCodeProject上找到了一个不错的。否则,将撤消和重做保留为包含其自己的私有数据副本的堆栈。

在撤销堆栈上,推送整个状态(您的求值树以及其他必要的状态)。确保状态不是通过引用共享的,例如,粗略地实现ICloneable。

这篇文章有点简短,但希望能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9802828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档