我正在使用Windows Forms编写一个简单的文本编辑器。与许多编辑器一样,当文本更改时,标题栏会在标题旁边显示一个星号,表示存在未保存的工作。当用户保存时,这就消失了。
然而,有一个问题。这是在主文本框的change事件中处理的。但是当打开文件或用户选择“新文件”时也会调用它,因此如果打开编辑器然后打开文件,程序会说有未保存的更改。什么是可能的解决方案?
我想过有一个全局变量,说明文本是否以不应触发星号的方式发生变化,但必须有更好的方法。
答案 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;
}
}