如何在C#中检测文本字段的先前状态?

时间:2009-07-23 03:25:30

标签: c# winforms text-editor

我正在使用Windows Forms编写一个简单的文本编辑器。与许多编辑器一样,当文本更改时,标题栏会在标题旁边显示一个星号,表示存在未保存的工作。当用户保存时,这就消失了。

然而,有一个问题。这是在主文本框的change事件中处理的。但是当打开文件或用户选择“新文件”时也会调用它,因此如果打开编辑器然后打开文件,程序会说有未保存的更改。什么是可能的解决方案?

我想过有一个全局变量,说明文本是否以不应触发星号的方式发生变化,但必须有更好的方法。

4 个答案:

答案 0 :(得分:1)

这是一个可怕的解决方案,但每次文本更改事件触发时,将文本框的值与某个变量进行比较,如果它们不同,则将文本框中的内容存储在变量中并添加星号。通过“新建文件”对话框或任何其他不更改文本的事件调用方法时,不会显示星号。

对于真正的文本编辑器来说,这不是一个可行的解决方案,因为即使是中等大小的文件,内存也会很快失控。使用手指树或编辑器用来比较文本“版本”的任何数据结构是唯一真正有效的解决方案,但前提是相同的。

http://scienceblogs.com/goodmath/2009/05/finally_finger_trees.php

在第二张图片下方,他提到在文本编辑器中使用手指树来实现极其便宜的“撤消”功能,但我相信你也可以看到树的有效性。

答案 1 :(得分:1)

在将数据加载到文本框之前,首先取消关联事件处理程序以进行更改

uxName.TextChanged -= uxName_TextChanged;    

uxName.Text = File.ReadAllText("something.txt");

uxName.TextChanged += uxName_TextChanged;

答案 2 :(得分:0)

C#中没有全局变量。你应该在表单中有一个变量作为实例变量(或者更好的是,在你的表单是视图的模型中),这非常好。

答案 3 :(得分:0)

这是一个非常简单和愚蠢的解决方案。我会使用MVP设计模式,但这里是最快速和最简单的解决方案:

//Declare a flag to block the processing of your event
private bool isEventBlocked = false;

private void OnTextChanged(object sender, EventArgs e)
{
    if(!isEventBlocked)
    {
        //do your stuff
    }
}

private void OnNewFile() //OR OnOpenFile()
{
    try
    {
        isEventBlocked = true;
        CreateFile();
    }
    catch
    {
        //manage exception
    }
    finally
    {
        isEventBlocked = false;
    }
}