views:

196

answers:

5

I'm coding a simple text editor using Windows Forms. As in many editors, when the text changes the title bar displays an asterisk next to the title, showing that there is unsaved work. When the user saves, this goes away.

However, there is a problem. This is handled in the change event of the main text box. But this gets called too when a file is opened or the user selects "New file", so that if you open the editor and then open a file, the program says that there are unsaved changes. What is a possible solution?

I thought of having a global variable that says whether the text changed in a way that shouldn't trigger the asterisk, but there has to be a better way.

A: 

There are no global variables in C#. You should have such an variable as an instance variable in your form (or better yet, in a model for which your form is a view), and that is perfectly fine.

Pavel Minaev
That's not really accurate. You can create a static class and add static variables to that class. Boom, global variables.
jasonh
Static variables aren't global. They're, well, static. I know this is somewhat pedantic, but I find it best to be precise with terms.
Pavel Minaev
Sorry, I meant an instance variable of the form. But I still don't like this solution.
Javier Badia
@Pavel: How aren't they global? What exactly is the difference?
jasonh
Technically because they are "static" and not global. Essentially they are the same thing but technically they are not. It's just semantics.
goldenratio
+1  A: 

This is a horrible solution, but every time the text change event fires, compare the value of the textbox to some variable, and if they are different store the contents on the textbox in a variable and add the asterisk. When the method is invoked via the New File dialog or any other such event that is NOT changing the text, the asterisk won't appear.

This is not a viable solution for a real text editor since the memory would quickly get out of hand on even medium-sized files. Using a finger tree or whatever data structure text editors use to compare "versions" of the text is the only real efficient solution, but the premise is the same.

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

Below the second picture he mentions the use of finger trees in text editors to implement an extremely cheap "undo" feature, but I'm sure you can see the validity of the tree for your problem as well.

goldenratio
No offense or anything, but this seems like overkill for what I'm trying to do.
Javier Badia
Well it seems like you are coding a text editor for fun. Implementing a cool data structure like a finger tree is pretty cool IMO.
goldenratio
A: 

before loading data to a textbox, unassociate first the eventhandler for change

uxName.TextChanged -= uxName_TextChanged;    

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

uxName.TextChanged += uxName_TextChanged;
Michael Buen
A: 

This is a very simple and stupid solution. I would use a MVP design pattern for this but here the fastest and simple solution:

//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;
    }
}
Francis B.
A: 

My answer is to use TextChanged event.

adatapost