Home > Software engineering >  How to add a saving function/button in c#?
How to add a saving function/button in c#?

Time:12-06

I made a note taking app in VS using C# and windows forms, but the save button only adds the "note" to the DataGridView I added to display the title and message of the "note", so when you close the application it deletes everything you wrote. I want to change it so when you close the app it actually saves all of your notes and restores them as they were. Can anybody help?

I looked it up but all I saw were SQL databases and tables, so since I'm quite new to programming I don't understand anything of that. And the explanations of those are also pretty crap. At least the ones I found.

CodePudding user response:

Add a method to your note taking app that will save the data from the DataGridView to a local file. You can use the StreamWriter class to write to a file, call this method when the user clicks the save button like this:

using (StreamWriter writer = new StreamWriter("C:\\data.txt"))
{
    for (int i = 0; i < dataGridView1.RowCount; i  )
    {
        for (int j = 0; j < dataGridView1.ColumnCount; j  )
        {
            writer.Write(dataGridView1[j, i].Value.ToString()   ",");
        }
        writer.WriteLine();
    }
}

To read the data from the file and populate the DataGridView you can use the StreamReader class, call this method when the app is opened like this:

using (StreamReader reader = new StreamReader("C:\\data.txt"))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        string[] values = line.Split(',');
        dataGridView1.Rows.Add(values);
    }
}

CodePudding user response:

Let's see if we can make this easy by letting DataGridView do most of the work. First make a class that has the public properties of a Note:

class Note
{
    public string Title { get; set; }
    public string Message { get; set; }
}

Next, make a BindingList to hold some Note objects. This will be the DataSource of the DataGridView.

BindingList<Note> Notes = new BindingList<Note>();

One way to save Notes is to write it as a Json file. (Make sure you have installed the Newtonsoft.Json NuGet and are using System.Linq and using Newtonsoft.Json).

private void save()
{
    // Do not block on this method
    BeginInvoke((MethodInvoker)delegate 
    {
        // Don't save a note if both fields are null.
        var onlyValidNotes = Notes.Where(_ => !(
            string.IsNullOrWhiteSpace(_.Title) &&
            string.IsNullOrWhiteSpace(_.Message)));
        File.WriteAllText(
            _jsonPath, 
            JsonConvert.SerializeObject(onlyValidNotes, Formatting.Indented));
    });
}

When the MainForm loads, we'll assign the DataSource, generate columns, and if there is already a saved notes.json file we can load it back in here. Call the save method whenever a Cell is done editing or when a row is removed.

protected override void onl oad(EventArgs e)
{
    base.OnLoad(e);

    dataGridView.DataSource = Notes;

    // Generate columns
    Notes.Add(new Note());
    dataGridView.Columns[nameof(Note.Title)].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    dataGridView.Columns[nameof(Note.Message)].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    Notes.Clear();

    // Read in the saved notes from last time.
    if (File.Exists(_jsonPath))
    {
        var json = File.ReadAllText(_jsonPath);
        var saved = JsonConvert.DeserializeObject<Note[]>(json);
        foreach (var note in saved)
        {
            Notes.Add(note);
        }
    }

    // Actions that trigger a save
    dataGridView.CellEndEdit  = (sender, e) => save();
    dataGridView.RowsRemoved  = (sender, e) => save();
}

And where do we save the data? One good choice is the user's local AppData file for this application. We can set this path in the MainForm CTor:

public MainForm()
{
    InitializeComponent();
    // Create a file path to persist the data.
    var appDataFolder = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        GetType().Assembly.GetName().Name
    );
    Directory.CreateDirectory(appDataFolder);
    _jsonPath = Path.Combine(appDataFolder, "notes.json");
}
readonly string _jsonPath;

screenshot

  • Related