You won't be able to access your Window1's DataGrid from Window2 directly.
You also not have access to your source collection (List) from Window2 to modify it from there.
In that facts, you got 2 ways:
- use external database;
- create public fixed collection of Students.
First of all and in any way I strongly recommend you to add some ID
field to your Student
object to be able unify each student.
If use external database
, you can simply call something like "UPDATE students s SET s.name = @name, s.age = @age... WHERE s.ID = @id"
from your Window2
when Save
button clicked. @name, @age ...
is new modified values
If use public fixed collection
, you can access it from any part of your program.
When Window2
Save button clicked, you can search for student in it by student's ID and simply edit him. After Window2
closing you need just refresh DataGrid view by resetting ItemsSource.
It may look like this:
Student class:
public class Student
{
// Need to be unique for each student
public int ID { get; private set; }
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
public string Major { get; set; }
public string Classification { get; set; }
public Student(int id)
{
ID = id;
Name = "SomeName";
Age = -1;
Gender = "Unknown";
Major = "Unknown";
Classification = "None";
}
// May also be overloaded with id, id+name, id+name+age, id+name+age+gender etc
public Student(int id, string name, int age, string gender, string major, string classification)
{
ID = id;
Name = name;
Age = age;
Gender = gender;
Major = major;
Classification = classification;
}
// If you need some kind of string representation of Student
public override string ToString()
{
return $"{ID},{Name},{Age},{Gender},{Major},{Classification}";
}
}
Fixed and public collection class to store Students:
public static class DB
{
// Your actual Database, where Students would be stored
private static readonly List<Student> students = new List<Student>();
// You can get it by DB.Students from anywhere
public static List<Student> Students { get { return students; } }
// As I see you use a file as source for item collection.
// You can add some Save() method to rewrite you existing
// file with items from "database":
// public static void Save()
// {
// StringBuilder sb = new StringBuilder();
//
// foreach (Student student in students)
// {
// sb.AppendLine(student.ToString());
// }
//
// File.WriteAllText("PathToYourFile", sb.ToString());
// }
//
// You should also override ToString method in Student class
// with something like (in format you wish):
// public override string ToString()
// {
// return $"{ID},{Name},{Age},{Gender},{Major},{Classification}";
// }
}
}
Update button click handler at Window1:
private void ButtonUpdate_Click(object sender, RoutedEventArgs e)
{
// There should be selected only 1 item or use dataGrid.SelectedItems[0]
if (dataGrid.SelectedItem is Student student)
{
// Pass selected Student to Window2
// where user will edit it
Window2 w2 = new Window2(student);
// Subscribe to Closed window to refresh DataGrid view after Student editing
w2.Closed += (s, a) =>
{
// Refresh the view of DataGrid by resetting its ItemsSource property
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = DB.Students;
};
// Show update window
w2.ShowDialog();
}
}
And some kind of Window2:
public partial class Window2 : Window
{
// Here would be a copy of Student object from Window1
// with which we would manipulate in Window2
// while editing in its fields
private readonly Student editableStudent = null;
public Window2(Student student)
{
InitializeComponent();
// Copy student object to store it in our Window2
// and be able to modify it not only from Constructor
editableStudent = student;
// Fill Window2 fields with existing Student values
tbName.Text = student.Name;
tbAge.Text = student.Age.ToString();
tbGender.Text = student.Gender;
tbMajor.Text = student.Major;
tbClassification.Text = student.Classification;
// Easy "on-the-fly" subscribe to each field TextChanged handlers to check,
// whether some data was changed/edited or not
// and save it to editableStudent
tbName.TextChanged += (s, a) =>
{
// Comparing value in field with existing Student's value
if (tbName.Text != student.Name) // May also check for not empty / or for min input length
{
// Saving new value to a copied object of our Student
editableStudent.Name = tbName.Text;
}
};
// Don't forget to check for integer value
// and convert in back to int:
// Convert.ToInt32(tbAge.Text)/int.Parse(tbAge.Text)/int.TryParse(tbAge.Text, out int age)
tbAge.TextChanged += (sender, args) => { /* Do same as with Name */ };
tbGender.TextChanged += (sender, args) => { /* Do same as with Name. */ };
tbMajor.TextChanged += (sender, args) => { /* Do same as with Name */ };
tbClassification.TextChanged += (sender, args) => { /* Do same as with Name */ };
}
private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
// Find index of Student element in our "Database" (List)
int index = DB.Students.FindIndex(x => x.ID == editableStudent.ID);
if (index != -1)
{
// Update record in a collection if it was found
DB.Students[index].Name = editableStudent.Name;
DB.Students[index].Age = editableStudent.Age;
DB.Students[index].Gender = editableStudent.Gender;
DB.Students[index].Major = editableStudent.Major;
DB.Students[index].Classification = editableStudent.Classification;
// Instead of use 'editableStudent' field with copied in
// constructor student's object, you can create it here
// and fill with values from TextBoxes in Window2.
// Or not create new Student object and fill new values
// directly in "database" by index.
// But you anyway need to store at least student's ID from
// student's object, passed from Window1, to be able to
// find him in "database"
// Student modifiedStudent = new Student(...);
// modifiedStudent.Name = tbName.Text;
// if (int.TryParse(tbAge.Text, out int age))
// modifiedStudent.Age = age;
// ...
// DB.Students[index].Name = modifiedStudent.Name;
// DB.Students[index].Age = modifiedStudent.Age;
// ...
// or
// DB.Students[index].Name = tbName.Text;
// if (int.TryParse(tbAge.Text, out int age))
// DB.Students[index].Age = age;
// ...
}
else
{
// Or message user if not found
MessageBox.Show("Student not found in Database (in a List of Students).");
}
// Close window after updating record in "Database"
// DataGrid view we will refresh from Window1 after
// Window2 close
Close();
}
private void ButtonCancel_Click(object sender, RoutedEventArgs e)
{
// Do nothing with Student, just close
Close();
}
}