Input/Output Practice Lab – C#

Input/Output Practice Lab

You are developer for NorthrupDevelopment, Inc., a software development company. Developers currently edit text files to configure settings in the development environment. However, there are often conflicts—for example, one developer might open a text file and forget to close it, preventing other users from editing it. Your management has asked you to create an application that allows developers to edit the text file without keeping the file locked open. Developers can save changes at will. If another developer saves changes while they have it open, the application should notify the developer.

To achieve your goals, you will create a text editor using the Windows Presentation Foundation (WPF). Then, you will add file monitoring capabilities. If another application changes the currently open text file, the application should display a dialog box notifying the user.

Exercise 1: Create a Text Editor

In this exercise, you will create a .NET Framework WPF application with a large text box for editing text. Additionally, you will create menu items that prompt the user to open and save the text file. The source code is available here: TextEditor Source Code, File Monitor Source Code.

Task 1: Create a WPF Application in either Visual Basic.NET or C#.

  1. Launch Visual Studio.
  2. Create a new WPF Application project in either Visual C# or Visual Basic. Name the application TextEditor.

Task 2: Create the user interface.

  1. Set the Windows.Title property to Text Editor
  2. Add a Menu control to the user interface.
  3. To the Menu.Items collection, add a MenuItem named FileMenu to represent the File menu.
  4. To the File MenuItem.Items, add two child MenuItem objects representing the Open and Save commands. Name the objects OpenMenuItem and SaveMenuItem.

The user interface should resemble the following:

Task 3: Write code to read and write files.

  1. Add the System.IO namespace to the project.
  2. Create the Click event handlers for both OpenMenuItem and SaveMenuItem. Use the default names assigned by VisualStudio.
  3. In the OpenMenuItem.Click event handler, write code to prompt the user to open a text file by using the Microsoft.Win32.OpenFileDialog. If the user opens a text file, read it and display it using the TextBox control.
  4. In the SaveMenuItem.Click event handler, write code to prompt the user to specify a filename. If a file with that name already exists, prompt the user to choose whether to overwrite it. Save the contents of the TextBox to the specified file.

The XAML code should resemble the following:

<Window x:Class="TextEditor.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Text Editor" Height="381" Width="489">
    <Grid>
        <Menu Height="22" Name="menu1" VerticalAlignment="Top">
            <MenuItem Name="FileMenu" Header="File">
                <MenuItem Name="OpenMenuItem" Header="Open" Click="OpenMenuItem_Click" />
                <MenuItem Name="SaveMenuItem"  Header="Save" Click="SaveMenuItem_Click" />
            </MenuItem>
        </Menu>
        <TextBox Margin="0,23,0,0" Name="textBox1" TextWrapping="Wrap" />
    </Grid>
</Window>

The C# code should resemble the following:

using System.IO;

namespace TextEditor
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void OpenMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Display an open file dialog
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.DefaultExt = ".txt";
            dlg.Filter = "Text documents (.txt)|*.txt";

            // Grab the user's response from the dialog
            Nullable<bool> result = dlg.ShowDialog();

            // If they picked a file, open it
            if (result == true)
            {
                // Open the file with a TextReader
                TextReader tr = File.OpenText(dlg.FileName);

                // Read the contents of the selected file into the TextBox
                textBox1.Text = tr.ReadToEnd();

                // Close the text file
                tr.Close();
            }
        }

        private void SaveMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Display a save file dialog
            Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
            dlg.DefaultExt = ".txt";
            dlg.Filter = "Text documents (.txt)|*.txt";

            // Grab the user's response from the dialog
            Nullable<bool> result = dlg.ShowDialog();

            // If they selected a filename...
            if (result == true)
            {
                // Create the file and write the contents of textBox1.Text to the file
                TextWriter tw = File.CreateText(dlg.FileName);

                tw.Write(textBox1.Text);

                // Close file
                tw.Close();
            }
        }
    }
}

Exercise 2: Monitor Files

In this exercise, you continue developing the application you created in the previous exercise. When the user opens a file, your application will begin monitoring the open text file for changes. If the opened file changes, the application will display a message box notifying the user of the change and prompting them to re-read the file from the file system. The application will not notify the user of changes made when saving the file, however.

Task 1: Add code to monitor file changes.

  1. At the class level, declare an instance of FileSystemWatcher named fsw.
  2. Within your code’s If statement that opens a file, declare two strings: folder and filename. You can use the System.IO.Path class to extract this information from dlg.FileName. Set folder to the specified file’s directory. Set filename to the file’s name.
  3. Define fsw using a new instance of the FileSystemWatcher class. In the FileSystemWatcher constructor, specify the folder String as the path, and specify the filename String as the filter.
  4. Configure fsw to monitor updates by setting NotifyFilters.LastWrite.
  5. Create and handle the FileSystemWatcher.Changed event for the fsw object.
  6. Set fsw.EnableRaisingEvents to true.
  7. In the FileSystemWatcher.Changed event handler, display a MessageBox warning the user that the open file was edited.
  8. When the user saves the file, set fsw.EnableRaisingEvents to false to prevent the application from warning the user that the file was edited while saving the file. Set fsw.EnableRaisingEvents to true after the save has been completed.

The updated C# code should now resemble the following:

using System.IO;

namespace TextEditor
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        // Declare a FileSystemWatcher so it can be accessed from multiple subroutines
        FileSystemWatcher fsw;

        public Window1()
        {
            InitializeComponent();
        }

        private void OpenMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Display an open file dialog
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.DefaultExt = ".txt";
            dlg.Filter = "Text documents (.txt)|*.txt";

            // Grab the user's response from the dialog
            Nullable<bool> result = dlg.ShowDialog();

            // If they picked a file, open it
            if (result == true)
            {
                // Open the file with a TextReader
                TextReader tr = File.OpenText(dlg.FileName);

                // Read the contents of the selected file into the TextBox
                textBox1.Text = tr.ReadToEnd();

                // Close the text file
                tr.Close();

                // Specify the path and filename for the FileSystemWatcher filter
                string folder = System.IO.Path.GetDirectoryName(dlg.FileName);
                string filename = System.IO.Path.GetFileName(dlg.FileName);
                fsw = new FileSystemWatcher(folder, filename);

                // Configure the events to respond to
                fsw.NotifyFilter = NotifyFilters.LastWrite;

                // Specify the Changed event handler
                fsw.Changed += new FileSystemEventHandler(fsw_Changed);
                fsw.EnableRaisingEvents = true;
            }
        }

        void fsw_Changed(object sender, FileSystemEventArgs e)
        {
            // Warn the user that their file was edited
            MessageBox.Show("WARNING: File was edited by another user", "File edited", MessageBoxButton.OK, MessageBoxImage.Warning);
        }

        private void SaveMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Display a save file dialog
            Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
            dlg.DefaultExt = ".txt";
            dlg.Filter = "Text documents (.txt)|*.txt";

            // Grab the user's response from the dialog
            Nullable<bool> result = dlg.ShowDialog();

            // If they selected a filename...
            if (result == true)
            {
                // Disable the FileSystemWatcher while we update the file
                fsw.EnableRaisingEvents = false;

                // Create the file and write the contents of textBox1.Text to the file
                TextWriter tw = File.CreateText(dlg.FileName);

                tw.Write(textBox1.Text);

                // Close file
                tw.Close();

                // Re-enable the FileSystemWatcher
                fsw.EnableRaisingEvents = true;
            }
        }
    }
}

Task 2: Test the application.

  1. Run the console application.
  2. Edit a text file.
  3. While keeping the file open in your TextEditor application, open it in Notepad. Edit the file and save it.
  4. Notice that the application warns you that another user edited the file.

Lab Resources

You can download the complete solutions here: TextEditor Source Code, File Monitor Source Code.

Return to the .NET Framework Fundamentals Tutorials Table of Contents.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>