question

HemanthB-9452 avatar image
0 Votes"
HemanthB-9452 asked SimpleSamples commented

Microsoft Visual Studio - Notepad

Hi, I recently created a notepad using Visual studio 2019. I added a save button to the notepad. Now how shall I code this:

When the user saves their file for the first time, the user selects their desired location in Windows, and once they save it in a location and continue editing their file, the save button again opens up the "Save as" dialog box. Is there any way that once the user saves their file for the first time and again edits it, it does not open up the "Save as" dialog box. And is there any way that if the user edits their file and clicks the close app button on top right without saving their changes, a dialog box appears saying: "Do you want save changes to your file"?

dotnet-csharp
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

SimpleSamples avatar image
0 Votes"
SimpleSamples answered SimpleSamples commented

I think this will do everything you are asking. Please test thoroughly.


 public partial class Form1 : Form
 {
     string Filename = null;
     string Previous = string.Empty;

     public Form1()
     {
         InitializeComponent();
     }

     private void exitToolStripMenuItem_Click(object sender, EventArgs e)
     {
         Close();
     }

     private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
     {
         if (SaveAs())
         {
             Previous = textBox1.Text;
         }
     }

     /// <summary>
     /// Saves to a file selected by the user
     /// </summary>
     /// <returns>true if something was saved</returns>
     private bool SaveAs()
     {
         SaveFileDialog sfd = new SaveFileDialog();
         sfd.Filter = "Text file|*.txt|All files|*.*";
         sfd.Title = "Save a text file";
         if (sfd.ShowDialog() != DialogResult.OK)
             return false;
         if (sfd.FileName == "")
             return false;
         try
         {
             using (StreamWriter sw = new StreamWriter(sfd.FileName))
             {
                 sw.Write(textBox1.Text);
                 Filename = sfd.FileName;
             }
         }
         catch (Exception ex)
         {
             MessageBox.Show("Write error: " + ex.Message);
             return false;
         }
         return true;
     }

     private void saveToolStripMenuItem_Click(object sender, EventArgs e)
     {
         if (Save())
         {
             Previous = textBox1.Text;
         }
     }

     /// <summary>
     /// Saves to the file; calls SaveAs if no previous file 
     /// </summary>
     /// <returns>true if something was saved</returns>
     private bool Save()
     {
         if (Filename == null)
         {
             bool saved = SaveAs();
             if (saved)
             {
                 Previous = textBox1.Text;
             }
             return saved;
         }
         try
         {
             using (StreamWriter sw = new StreamWriter(Filename))
             {
                 sw.Write(textBox1.Text);
             }
         }
         catch (Exception ex)
         {
             MessageBox.Show("Write error: " + ex.Message);
             return false;
         }
         return true;
     }

     private void closeToolStripMenuItem_Click(object sender, EventArgs e)
     {
         AskToSave();
     }

     private void AskToSave()
     {
         if (textBox1.Text == Previous)
         {
             Filename = null;
             return;
         }
         DialogResult dr = MessageBox.Show(
             "Do you wish to save changes?",
             "Unsaved changes",
             MessageBoxButtons.YesNo,
             MessageBoxIcon.Question
             );
         if (dr != DialogResult.Yes)
             return;
         Save();
         Previous = string.Empty;
         Filename = null;
     }

     private void openToolStripMenuItem_Click(object sender, EventArgs e)
     {
         OpenFileDialog ofd = new OpenFileDialog();
         ofd.Filter = "Text file|*.txt|All files|*.*";
         if (ofd.ShowDialog() != DialogResult.OK)
             return;
         try
         {
             using (StreamReader sr = new StreamReader(ofd.FileName))
             {
                 Previous = sr.ReadToEnd();
                 textBox1.Text = Previous;
                 Filename = ofd.FileName;
             }
         }
         catch (Exception ex)
         {
             MessageBox.Show("Read error: "+ex.Message);
         }
     }

     private void Form1_FormClosing(object sender, FormClosingEventArgs e)
     {
         AskToSave();
     }
 }
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi, your code did work perfectly but I have a new problem! If I write something and close without saving previously, a message box appears right, now when I click Yes a dialog box appears (the file explorer dialog box). Next when I click the close button (X Button) on top of the file explorer dialog (As shown in the image), the entire application closes instead of only the file explorer dialog box closing and my work is lost! Please help me with this problem.


102634-sc.png


0 Votes 0 ·
sc.png (18.2 KiB)

Yes, that is how I designed it. You can change that to do whatever you want; just decide what you want it to do. But the sample code is doing what it is designed to do. You should study the code and ensure you understand how it works. There are many possible modifications and/or improvements; for example some editors have a New command (menu item) instead of Close. Also, you can save the filename and directory (or just the entire path) in a setting so the user can open a file from where a file was opened previously.

0 Votes 0 ·
karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered karenpayneoregon commented

Here is a mockup which uses a private variable that would in your case know if there are unsaved changes. A CheckBox allow simulation of if a prompt is needed on form closing event.

 using System;
 using System.ComponentModel;
 using System.Windows.Forms;
 using static WindowsFormsApp1.Dialogs;
    
 namespace WindowsFormsApp1
 {
     public partial class Form1 : Form
     {
         public Form1()
         {
             InitializeComponent();
             Closing += OnClosing;
         }
    
         private void OnClosing(object sender, CancelEventArgs e)
         {
             if (!_hasChanges) return;
                
             if (Question("Save changes?"))
             {
                 e.Cancel = true;
             }
    
         }
    
         private bool _hasChanges;
         private void checkBox1_CheckedChanged(object sender, EventArgs e)
         {
             _hasChanges = checkBox1.Checked;
         }
     }
 }

MessageBox wrapper (optional, you can do it your way) which defaults to the No button.

 using System.Windows.Forms;
    
 namespace WindowsFormsApp1
 {
     public static class Dialogs
     {
         public static bool Question(string text) => 
         (
             MessageBox.Show(text, "Question", 
                 MessageBoxButtons.YesNo, MessageBoxIcon.Question, 
                 MessageBoxDefaultButton.Button2) == DialogResult.Yes);
    
     }
 }


· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

98822-untitled.png



This error is showing up. Please help!

0 Votes 0 ·
untitled.png (125.7 KiB)

checkBox1 is a standard CheckBox placed on the form from Visual Studio's toolbox. Which means your checkbox1 is not a CheckBox as the error message indicates checkBox1 in your case is an object.

So to fix this you need a CheckBox named checkBox1 from the IDE toolbox.

0 Votes 0 ·

Also, you seem to have reinvented my Question method, why? Should be using mine as the code is right there.

0 Votes 0 ·
ArtemiyMorozUA avatar image
0 Votes"
ArtemiyMorozUA answered

hi there!

The idea is that you need to create a variable called "SavedFlag" in your program. For new file you set SavedFlag to false. Once the user saves the text, you set the SavedFlag to true. Upon pressing "Save" button, you check the SavedFlag. If it is already true, then you just write the file. If the flag is false, you call the SaveFileDialog procedure.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.