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;