[Part3]C# - TextEditor (Windows Form)

04/28/2010 00:28 ©Hyperlink#1
Now we will look at some more advanced things like creating a text editor, with load/save files.
First create a windowsformapplication.
Make sure you name it:
TextEditor
Now delete the "Form1.cs".
Now right click at your solution and choose:
Add > Windows Form
Make the name:
TextEditor
Now make the design fit into what you want.
Now create 3 buttons.
Quote:
Button1 Name: btnLoadFile
Button1 Text: Load File

Button2 Name: btnSaveFile
Button2 Text: Save File

Button3 Name Button3
Button3 Text: New File
Now double click at them all.
So you will get 3 codes.
Now we will need the new project button to create new project.
We will do it, so it close the old and opens a new.
Just inside Button3 make it opens it again and close it.
You can do it like this:
At top find using System.Windows.Forms;
under it paste:
Code:
using System.Diagnostics;
using System.Threading;
Then the button could look like this:
Code:
        private void button3_Click(object sender, EventArgs e)
        {
            MessageBox.Show("The latest project will now not be save."); //Will send a message box before creating new project
            System.Diagnostics.Process.Start("C:/"); //The path of the run for program
            Thread.Sleep(200); //Letting this methode sleep, so it have time to open the new
            Application.Exit(); //Closing the first program
        }
Now it will close & open a new :)
Okay now for making it load a file.
First you will need to make a textbox.
Make it fit into what you want.
Call it:
txtFileContent
Then make the Anchor:
Top, Bottom, Left, Right
And change the font to:
Consolas; 8pt
You can also change the text color.
But is not realyl important.
Make scrollbars:
Both
if you want text to be there at start, just find "text".
And edit it to what you want.
Now double click at your load button.
Then find:
Code:
public partial class TextEditor : Form
under it put:
Code:
        private string _fileName;
        private FileSystemWatcher _fileMonitor;

        private bool _wasChanged;
        private bool _wasRenamed;
        private bool _wasCreated;

        public delegate void LoadContentCallback();
it should look like this:
Code:
namespace TextEditor
{
    public partial class TextEditor : Form
    {
        private string _fileName;
        private FileSystemWatcher _fileMonitor;

        private bool _wasChanged;
        private bool _wasRenamed;
        private bool _wasCreated;

        public delegate void LoadContentCallback();
Now change the public TextEditor()
with:
Code:
        public TextEditor()
        {
            InitObjects();

            InitializeComponent();
        }
Now for the button.
This should be the sub for it:
private void btnLoadFile_Click(object sender, EventArgs e)
It should already be there.
Find it.
We just want it to open the load file thing.
Is called OpenFileDialog.
It could be used like this:
Code:
private void btnLoadFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            ofd.CheckFileExists = true;
            ofd.Multiselect = false;

            DialogResult result = ofd.ShowDialog();

            if (result == DialogResult.OK)
            {
                _fileName = ofd.FileName;

                if (_fileName != string.Empty)
                    LoadFileContent();
            }
        }
We will need a content for whats happening and for checking the file.
So below this you will need to make a content.
It could look like this:
Code:
        private void LoadFileContent()
        {
            lblFileName.Text = Path.GetFileName(_fileName);

            try
            {
                TextReader tr = new StreamReader(_fileName);
                try
                { txtFileContent.Text = tr.ReadToEnd(); }
                catch (Exception ex)
                { MessageBox.Show(ex.Message); }
                finally
                {
                    tr.Close();

                    StartMonitorization();
                }
            }
            catch (FileNotFoundException ex)
            { MessageBox.Show("Sorry, the file does not exist."); }
            catch (UnauthorizedAccessException ex)
            { MessageBox.Show("Sorry, you lack sufficient privileges."); }
            catch (Exception ex)
            { MessageBox.Show(ex.Message); }
        }
Also now you will need a start monitor.
To check for file changes.
It can be done like this:
Code:
        private void StartMonitorization()
        {
            _fileMonitor = new FileSystemWatcher(Path.GetDirectoryName(_fileName), Path.GetFileName(_fileName))
                               {
                                   NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite,
                                   IncludeSubdirectories = false
                               };

            _fileMonitor.Changed += FileMonitor_OnChanged;
            _fileMonitor.Created += FileMonitor_OnChanged;
            _fileMonitor.Deleted += FileMonitor_OnDeleted;
            _fileMonitor.Renamed += FileMonitor_OnRenamed;

            _fileMonitor.EnableRaisingEvents = true;
        }
And the controls for it could look like this:
Code:
private void StartMonitorization()
        {
            _fileMonitor = new FileSystemWatcher(Path.GetDirectoryName(_fileName), Path.GetFileName(_fileName))
                               {
                                   NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite,
                                   IncludeSubdirectories = false
                               };

            _fileMonitor.Changed += FileMonitor_OnChanged;
            _fileMonitor.Created += FileMonitor_OnChanged;
            _fileMonitor.Deleted += FileMonitor_OnDeleted;
            _fileMonitor.Renamed += FileMonitor_OnRenamed;

            _fileMonitor.EnableRaisingEvents = true;
        }

        private void FileMonitor_OnRenamed(object sender, RenamedEventArgs e)
        {
            if (!_wasRenamed)
            {
                DialogResult result = MessageBox.Show("The file " + e.OldName + " was renamed. \r\n" +
                                                    "Do you want to load the new file ?", "File was renamed", MessageBoxButtons.OKCancel);

                _wasRenamed = true;

                if (result == DialogResult.OK)
                {
                    _fileName = e.FullPath;
                    this.BeginInvoke(new LoadContentCallback(LoadFileContent));
                }
            }
            else
            {
                _wasRenamed = false;
            }

        }

        private void FileMonitor_OnDeleted(object sender, FileSystemEventArgs e)
        {
            DialogResult result = MessageBox.Show("The file " + e.Name + " was deleted. \r\n" +
                                                  "Do you want to remove it from text editor ?", "File was deleted",
                                                  MessageBoxButtons.YesNo);

            if (result == DialogResult.Yes)
            {
                _fileMonitor.Dispose();

                this.BeginInvoke(new LoadContentCallback(ResetUiContent));
            }

        }

        private void FileMonitor_OnChanged(object sender, FileSystemEventArgs e)
        {
            if ((!_wasCreated && e.ChangeType == WatcherChangeTypes.Created) ||
                (!_wasChanged && e.ChangeType == WatcherChangeTypes.Changed))
            {
                DialogResult result = MessageBox.Show("The content of the file " + e.Name + " was changed. \r\n" +
                                                      "Do you want to reload it ?", "File was changed",
                                                      MessageBoxButtons.OKCancel);

                if (e.ChangeType == WatcherChangeTypes.Changed)
                {
                    _wasChanged = true;
                }
                else
                {
                    _wasCreated = true;
                }

                if (result == DialogResult.OK)
                {
                    this.BeginInvoke(new LoadContentCallback(LoadFileContent));
                }
            }
            else
            {
                if (e.ChangeType == WatcherChangeTypes.Changed && _wasChanged)
                {
                    _wasChanged = false;
                }
                else if (e.ChangeType == WatcherChangeTypes.Created && _wasCreated)
                {
                    _wasCreated = false;
                }
            }
        }

        private void ResetUiContent()
        {
            txtFileContent.Text = string.Empty;
            lblFileName.Text = string.Empty;
            _fileName = string.Empty;
        }
Now our code should look like:

Okay next step is to make it save our file.
Is also the last step.
Basicly is the same as the Load.
But this time it have to create a file.
And check for wich filetypes it supports.
(Look buttom for how to add more filetypes)
This could be used as the save button:
Code:
private void btnSaveFile_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "C# files (*.cs)|*.cs|HTML Files (*.html)|*.html|DAT Files (*.dat)|*.dat|INI Files (*.ini)|*.ini";

            saveFileDialog.SupportMultiDottedExtensions = true;

            DialogResult result = saveFileDialog.ShowDialog();

            if (result == DialogResult.OK)
            {
                _fileName = saveFileDialog.FileName;
                
                if (!string.IsNullOrEmpty(_fileName))
                    SaveFileContent();
            }
        }

        private void SaveFileContent()
        {
            lblFileName.Text = Path.GetFileName(_fileName);

            try
            {
                // we'll make only a textual file for instance
                TextWriter tw = File.CreateText(_fileName);

                try
                {
                    tw.Write(txtFileContent.Text);
                }
                catch (Exception ex)
                { MessageBox.Show(ex.Message); }
                finally
                {
                    tw.Close();

                    StartMonitorization();
                }
            }
            catch (UnauthorizedAccessException ex)
            { MessageBox.Show("Fail. You lack sufficient privileges."); }
            catch (Exception ex)
            { MessageBox.Show(ex.Message); }
        }

        private void TextEditor_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Modifiers == Keys.Control)
            {
                switch (e.KeyCode)
                {
                    case Keys.S:
                        btnSaveFile_Click(btnSaveFile, null);
                        break;
                    case Keys.O:
                        btnLoadFile_Click(btnSaveFile, null);
                        break;
                }
            }
        }
Now you will get 1 error and maybe a warning.
Open Program.cs
Find:
Code:
Application.Run(new Form1());
Replace it with this because your name of the Form is TextEditor
Code:
Application.Run(new TextEditor());
Now your text editor should work fine.
There is only 1 thing.
That will be showed as a warning or a note for you.
Is because is declared, but never used.
The line is:
Code:
catch (FileNotFoundException ex)
catch (UnauthorizedAccessException ex)
catch (UnauthorizedAccessException ex)
You don't really have to do anything here.
Don't give me credits for this.
I only took Code4Food's tutorial and fixed some things on it.

In part4 We will look at:
Browser inside Windows Form.


It works fine, there shouldn't be any problems.
If there still is problems, make a reply or PM me.


-------------------------------
Final script:

TextEditor.cs:

Program.cs

Design: