[C#/WPF] kNotepad - a Simpler Notepad Clone

Hey everyone,
I had some time last night so I decided to write a simple Notepad clone application using C# and WPF. You can see the screenshot here:

[ Install by clicking here ]

You can see the C# code (also attached):

using System;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using Microsoft.Win32;
using System.Text;
using System.Windows.Input;
using System.ComponentModel;
namespace kNotepad
{
    public partial class MainApp
    {
        private bool dataChanged = false;
        private string filePath = null;
        public MainApp()
        {
            this.InitializeComponent();
        }
        //
        // When New is selected from the Menu
        //
        private void NewItem(object sender, RoutedEventArgs e)
        {
            ProcessNewCommand();
        }
        //
        // When New is selected from the Menu
        //
        private void OpenItem(object sender, RoutedEventArgs e)
        {
            ProcessOpenCommand();
        }
        //
        // When Save is selected from the Menu
        //
        private void SaveItem(object sender, RoutedEventArgs e)
        {
            ProcessSaveCommand();
        }
        //
        // When Save As is selected from the Menu
        //
        private void SaveAsItem(object sender, RoutedEventArgs e)
        {
            ShowSaveDialog();
        }
        //
        // When Exit is selected from the Menu
        //
        private void ExitItem(object sender, RoutedEventArgs e)
        {
            if (dataChanged)
            {
                SaveFirst();
                this.Close();
            }
            else
            {
                this.Close();
            }
        }
        //
        // Display Open File dialog window
        //
        private void ShowOpenDialog()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Text Files|*.txt|All|*.*";
            //
            // If user selected a file and pressed OK, process it.
            //
            if (ofd.ShowDialog() == true)
            {
                filePath = ofd.FileName;
                ReadFile(filePath);
                SetTitle(ofd.SafeFileName);
                dataChanged = false;
            }
        }
        //
        // When given a file path, read that information and load it into the textfield
        //
        private void ReadFile(string path)
        {
            StreamReader reader = new StreamReader(path);
            StringBuilder sb = new StringBuilder();
            string r = reader.ReadLine();
            while (r != null)
            {
                sb.Append(r);
                sb.Append(Environment.NewLine);
                r = reader.ReadLine();
            }
            reader.Close();
            //
            // Sending text data to the text box
            //
            txtBoxContent.Text = sb.ToString();
        }
        //
        // Given a path to a file, write the contents of the textbox into it
        //
        private void SaveFile(string path)
        {
            StreamWriter writer = new StreamWriter(path);
            writer.Write(txtBoxContent.Text);
            writer.Close();
            dataChanged = false;
        }
        //
        // Display the Save Dialog window to specify the location to save your file
        //
        private void ShowSaveDialog()
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Text Document (.txt)|*.txt";
            bool? saveResult = sfd.ShowDialog();
            if (saveResult == true)
            {
                string s = sfd.FileName;
                filePath = s;
                SaveFile(s);
                SetTitle(sfd.SafeFileName);
            }
        }
        //
        // Ensure that your save your changes before doing anything that might alter your textbox contents or close the program
        //
        private string SaveFirst()
        {
            MessageBoxResult mbr = MessageBox.Show("Do you want to save your changes first?", "Save File?", MessageBoxButton.YesNoCancel);
            if (mbr == MessageBoxResult.Yes)
            {
                if (filePath != null)
                {
                    SaveFile(filePath);
                }
                else
                {
                    ProcessSaveCommand();
                }
            }
            else if (mbr == MessageBoxResult.Cancel)
            {
                return "Cancel";
            }
            return "Nothing";
        }
        //
        // Clears all of the information from the screen
        //
        private void ClearState()
        {
            filePath = null;
            dataChanged = false;
            txtBoxContent.Text = "";
            ResetTitle();
        }
        //
        // Display the About Dialog window
        //
        private void ShowAbout(object sender, RoutedEventArgs e)
        {
            ShowAboutDialog();
        }
        //
        // Process the details about where the About Dialog window will actually show
        //
        private void ShowAboutDialog()
        {
            About a = new About();
            a.WindowStartupLocation = WindowStartupLocation.Manual;
            a.Left = this.Left + 75;
            a.Top = this.Top + 75;
            a.ShowDialog();
        }
        //
        // Determine best way to Save document
        //
        private void ProcessSaveCommand()
        {
            if (filePath == null)
            {
                ShowSaveDialog();
            }
            else
            {
                SaveFile(filePath);
            }
        }
        //
        // Determine best way to setup New document
        //
        private void ProcessNewCommand()
        {
            if (dataChanged)
            {
                string sf = SaveFirst();
                if (sf != "Cancel")
                {
                    ClearState();
                }
            }
            else
            {
                ClearState();
            }
        }
        //
        // Determine best way to Open document
        //
        private void ProcessOpenCommand()
        {
            if (dataChanged)
            {
                SaveFirst();
                ShowOpenDialog();
            }
            else
            {
                ShowOpenDialog();
            }
        }
        //
        // Save document before closing application
        //
        private void AppClosing(object sender, CancelEventArgs e)
        {
            if (dataChanged)
            {
                SaveFirst();
            }
        }
        //
        // Whenever a key is pressed inside the text field, take care of it
        //
        private void ContentChanged(object sender, KeyEventArgs e)
        {
            dataChanged = true;
        }

        //
        // This is done to check whether our content had changed or not
        //
        private void FocusChanged(object sender, RoutedEventArgs e)
        {
            dataChanged = true;
        }
        //
        // Process Key Combinations for Saving, New, and Open
        //
        private void KeyCombinations(object sender, KeyEventArgs e)
        {
            // Ctrl + S
            if ((Keyboard.Modifiers == ModifierKeys.Control) && (e.Key == Key.S))
            {
                ProcessSaveCommand();
            }
            // Ctrl + N
            if ((Keyboard.Modifiers == ModifierKeys.Control) && (e.Key == Key.N))
            {
                ProcessNewCommand();
            }
            // Ctrl + O
            if ((Keyboard.Modifiers == ModifierKeys.Control) && (e.Key == Key.O))
            {
                ProcessOpenCommand();
            }
        }
        //
        // Change the Window title to include the file's name when opened or saved
        //
        private void SetTitle(string newTitle)
        {
            Window.Title = "kNotepad - " + newTitle;
        }
        //
        // Reset the Window Title
        //
        private void ResetTitle()
        {
            Window.Title = "kNotepad";
        }
    }
}

And the XAML markup is only:

<Window
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xml:lang="en-US"
 x:Class="kNotepad.MainApp"
 x:Name="Window"
 Title="kNotepad"
 Width="640" Height="480" Icon="note.png" Closing="AppClosing" KeyUp="KeyCombinations">
 <Grid x:Name="gridMain">
  <Menu Margin="0,0,2,0" x:Name="menuMain" VerticalAlignment="Top" Height="20">
   <MenuItem x:Name="mnuFile" Header="File">
    <MenuItem x:Name="mnuItemNew" InputGestureText="Ctrl+N" Header="New" Click="NewItem"/>
    <MenuItem x:Name="mnuItemOpen" InputGestureText="Ctrl+O" Header="Open" Click="OpenItem"/>
    <MenuItem x:Name="mnuItemSave" InputGestureText="Ctrl+S" Header="Save" Click="SaveItem"/>
    <MenuItem RenderTransformOrigin="0.498,-1.5" x:Name="mnuItemSaveAs" Header="Save As..." Click="SaveAsItem"/>
    <Separator/>
    <MenuItem x:Name="mnuItemExit" Header="Exit" Click="ExitItem"/>
   </MenuItem>
   <MenuItem x:Name="mnuHelp" Header="Help">
    <MenuItem x:Name="mnuItemAbout" Header="About" Click="ShowAbout"/>
   </MenuItem>
  </Menu>
  <TextBox Margin="0,20,0,0" x:Name="txtBoxContent" FontFamily="Courier New" Text="" TextWrapping="Wrap" AcceptsReturn="True" AcceptsTab="True" VerticalScrollBarVisibility="Auto" GotFocus="FocusChanged" KeyDown="ContentChanged"/>
 </Grid>
</Window>

Some of the code might be interesting such as how to fire a method when an application close is detected, how to use Key Combinations, etc.

Cheers!
Kirupa :cap: