Deleting data from a list from a second form - c#

I have a form that where I read in a csv file containing student information, the file has two columns StudentNumber and Mark. I want to allow the user to click a button on the first form to then go to another form called deleteRecord On this form the user will type in a StudentNumber and a Mark and the record that corresponds with them two pieces of information will be delete from the list.
Since I am new to C# I am not sure on how to go about this so any help will be appreciated.
My list:
public static List<string> studentInfo = new List<string>();
I store all the data from that list in a listbox called lstMarks
I want to also confirm to the user that the record was deleted successfully.

If all the data is stored in the list, simply use LINQ and add a number for each student in the list for the index.
First you'll need to create a class and (I recommend it) put it in a folder.
How it looks.
Then you'll have to put the propreties in the class:
public class Student
{
public int StudentNumber {get; set;}
public int Mark {get; set;}
public int Index {get; set;}
}
Now add another class with the list:
partial class MainWindow : Window
{
private List<Student> _studentInfo = new List<Student>()
{
new Student() {Index = 0, StudentNumber = 0, Mark = 0}
// ...
}
And then add using at the top of your code of deleteRecord and the name of the folder and the two classes:
using ExampleFolder.Class;
You'll need to call your Student class to be able to modify the StudentNumber and Mark and Index.
Student studentInfo = new Student();
int iIndex = 0;
var req = from info in studentInfo
where info.StudentNumber == txtStudentNumber && info.Mark == txtMarks
select info.Index; // Starts with 0 for the first student in the list
foreach(var num in req)
{
iIndex = num;
}
studentInfo.Remove(studentInfo[iIndex]);
MessageBox.Show("Deleted!");

Related

Convert List<string> to Model class

Having issue with converting List to Student object in c#.
I have a C# model class as below:
public class Student{
public int ID{get;set;}
public string StudentName{get; set;}
public string StudentAddress{get; set;}
public string StudentRemarks{get; set;}
public string AdditionalInfo{get;set;}
}
I have another class where I have a List which holds data as below (Since this is just a list of string, it won't have any property names in front of it such as 'ID: 001') Note: This string will not have any data for 'AdditionalInfo'.
001
John, Snow
NewYork
Sample test info
Now I have another class where I wanted to convert this List to my 'Student' class where 001 has to be assigned to ID, John Snow has to be assigned to 'StudentName', NewYork has to be assigned to 'StudentAddress', Sample test info has to be assigned to 'StudentRemarks'. Since this doesn't have any data provided for 'AdditionalInfo' property, this should be assigned with empty or null value in it. Here is the class
public class StudentInfoService
{
public List<string> GetStudentInfo(string data)
{
var studentData = new List<string>();
foreach (var line in File.ReadLines(data))
{
if (!string.IsNullOrWhiteSpace(line))
{
var data = line.Split('|');
foreach (var item in data)
{
studentData.Add(item);
}
studentData.ConvertAll(c => (Student)c); //Here is where I am struggling to convert the list string to model class
}
}
return studentData ;
}
}
The issue is, I want to convert the list to 'Student' object and automatically assign all the data to the respective properties by order(there won't be any null or empty data in between other than the 'AdditionalInfo'). Student object will have only one student record. It won't have a list of records. So I need to convert the List to Student object. Please help me with this.
You will need to write code to map lines of text to a model instance, e.g.
public Student GetStudent(List<string> list)
{
return new Student
{
ID = int.Parse(list[0]),
StudentName = list[1],
StudentAddress = list[2],
StudentRemarks = list[3],
AdditionalInfo = (list.Count > 4) ? list[4] : null
};
}

Indexes that correspond to each other in two Lists

I have two Lists:
List<string> names = new List<string>();
List<int> goals = new List<int>();
One of them is a string List while the other one is a int List. I add some numbers in the second List, and then I get the biggest number in the List. This works.
Now I need to type some names in the console and after each name I need to type a certain number and this repeats to whenever I want.
How do I get the index of the biggest number in the second list and to print it alongside the name that actually have "scored" that biggest number? I want to get the index from the first string List that corresponds to the index of the biggest number in the second List. Is there a way that I can do it?
In your case, "Name" and "Goals" relate to each other. Someone or something with a "Name" has obviously attached to them a number of "Goals". So, let's reflect this relation in a class:
public class StatisticsItem
{
// Properties here
public string Name {get; set;}
public int Goals {get; set;}
}
You then can create new instances of that class like so:
var item = new StatisticsItem() { Name = "Marc", Goals = 5 };
and you can put those in a list:
var myList = new List<StatisticsItem>();
myList.Add(item);
Find your champion:
using System.Linq;
// ...
Console.WriteLine("Goalie King: {0}", myList.MaxBy(x => x.Goals).Name);
See in action: https://dotnetfiddle.net/I9w5u7
To be a bit more clean, you could of course use a constructor:
public class StatisticsItem
{
// Properties here
public string Name {get; set;}
public int Goals {get; set;}
public StatisticsItem(string name, int goals)
{
Name = name;
Goals = goals
}
}
// and then create instances like so:
var item = new StatisticsItem("Marc", 5);
Can't comment so i will add my opinion here. Fildor suggested 1 list with 2 properties which should cover your case. I would say also check if a dictionary<string, int> or a dictionary<string, List<int>> is a better fit instead of a list.
Keep in mind for a dictionary to work the key (name in your case) must be unique. If not discard this answer

Inconsistent information in DataGrid using List Concat c# wpf

I have one table called Registry, in a Registry class.
It contains
Number, Description, People_id
People_id is a foreign key from People table, in a People class.
It contains
id, Name, birth_date
I need to show all the data from the Registry table in a DataGrid and the age for the People_id (calculated with the birth_date) in the Registry table. I already can retrieve all the Registry data and show it on the Datagrid but I'm missing the Age part.
I tried with something like this. Retrieve the Registry data, foreach to get Birth Dates, do the calculation and fill a List with only the Age result. Then, join the two List with the Concat method in a new List called CombRegistryAge as you can see below in the first method.
public List<object> RegistryJoinAge()
{
List<object> ResultAge = new List<object>();
List<Registry> ListRegistry = new Registry().LoadRegistry();
//method LoadRegistry retrieve all items in Registry table
foreach (var item in ListRegistry)
{
var age = AgeCalculation(item.People.birth_date);
ResultAge.Add(age);
}
List<object> CombRegistryAge = ListRegistry.Cast<object>().Concat(ResultAge).ToList();
return CombRegistryAge;
}
For the AgeCalculation method, something simple to start testing
private int AgeCalculation(DateTime birthdate)
{
var todayIs = DateTime.Today;
int age = todayIs.Year - birthdate.Year;
return age;
}
But when I call the method using the List CombRegistryAge in the datagrid
datagrid_fillData.ItemsSource = RegistryJoinAge();
I still get the Registry data inside but not Age and I noticed, from the datagrid, it adds empty rows for every age calculated but in reality, I need them to be show as a single one, something like this in the datagrid.
Id, Description, People_id, Age
101, Passed, 1802, 35
That's my doubt. Maybe it's a problem with the List because I tried reversing the list order in the concat method but it show and empty grid.
Any help with be appreciated.
I will suggest you create a class UserRegistryModel, to carry your data which can binding data in datagrid.
public class UserRegistryModel
{
public int Number { get; set; }
public string Description { get; set; }
public int People_id { get; set; }
public int Age { get; set; }
}
Use Lambda select make the code more clear.
public List<UserRegistryModel> RegistryJoinAge()
{
List<UserRegistryModel> ListRegistry = new Registry().LoadRegistry()
.select(x => new UserRegistryModel()
{
Number = x.Number,
Description = x.Description,
People_id = x.People_id,
Age = AgeCalculation(x.People.birth_date)
}).ToList();
return ListRegistry;
}
Final return UserRegistryModel List

How to search an element of an array and display

I need to display the grade each student has by asking for it's number. The grade each student has is tied with each student, can be the array place of each. The Student number is what is prompted to ask the search in the array. Could it possibly be done in a short Two liner?
using System;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string[] studentName = {"Bob","Marie","Nathan","Lois","Sam"};
string[] studentsNumber = {"040707701","040707702","040707703","040707704","040707705"};
string[] studentGrade = {"A","B","C","D","F"};
string studentsNumber = "";
Console.WriteLine("What is your student number");
Console.ReadLine(studentsNumber.ToString());
for(int index = 0, studentNumber[studentNumber - 1], index++)
{
Console.WriteLine(studentsNumber[index]);
onsole.WriteLine(studentName[],studentGrade[] {0} {1});
}
}
}
}
Since this is homework, I'm not going to give you the answer outright but give you a hint instead.
Once you have the student number, loop through the array of student numbers. Once you find the index of the matching number...you can use that to retrieve the grade.
Keep in mind, though, that arrays aren't the right way to solve this problem at all. You'd be much better off creating a class for student that included name, number, and grade. You could then create instances of the class and add those instances to a List that you could then iterate through.
Would be much better to have an object:
public class StudentInfo
{
public string Name {get; set;}
public string Grade {get; set;}
public int Number {get; set;}
}
And then have a List<StudentInfo>.
By doing it this way your data will be tight together. Otherwise you might end up in a situation where you have different number of items in each array and you wouldn-t know which one is which.
Hope it helps.
eek!
Why not use an anonymous class with a bit of linq?
var students = new[]
{
new { Name = "Bob", Number = "040707701", Grade = "A" },
...
};
var grade = students.Where(s => s.Number == "040707701").Select(s => s.Grade);

LINQ - Help me grasp it with an example I think LINQ should be able to solve!

I am trying to get into LINQ to objects as I can see the power of it. Lucky enough I have a question that I think LINQ should be able to solve.
Here is the question (the details are an example);
public class SchoolClass
{
public int ID;
public string Name;
public string Teacher;
public string RoomName;
public string Student_Name;
public int Student_Age;
}
As you can see by the example, there is a one to many relationship between the ClassName, Teacher and Room and the Students, i.e. there are potentially many students in the one class.
If we have a List is it possible using LINQ to create a List but have only one instance ID, Name, Teacher, RoomName and an ArrayList of Student_Name and Age?
Producing this:
public class Students
{
public string Student_Name;
public int Student_Age;
}
public class SchoolClass
{
public int ID;
public string Name;
public string Teacher;
public string RoomName;
public ArrayList Students;
}
Essentially, using LINQ to clean the List to a more logical structure?
To give some background to this example. The second structure is used by a DataGrid to produce a Master-Child relationship. We store SchoolClass and StudentInformation in classes as shown above. It would be good use of LINQ to be able to convert our initial List into a structure which can be used by the DataGrid.
I changed the ArrayList to List<Students>, and:
List<SourceData> source = new List<SourceData>();
//...your data here ;-p
var classes = (from row in source
group row by new {
row.ID, row.Name,
row.Teacher, row.RoomName }
into grp
select new SchoolClass
{
ID = grp.Key.ID,
Name = grp.Key.Name,
Teacher = grp.Key.Teacher,
RoomName = grp.Key.RoomName,
Students = new List<Students>(
from row in grp
select new Students
{
Student_Age = row.Student_Age,
Student_Name = row.Student_Name
})
}).ToList();
If I'm understanding this correctly, I would've thought the best way to implement the SchoolClass class would be to create a Student class (probably a LINQ-to-SQL entity, if you're using it) and to have a generic list of type student, something similar to this:
public class SchoolClass
{
public int ID;
public string Name;
public string Teacher;
public string RoomName;
public List<Student> Students;
}
The list of students could then be populated using a linq query, although I'm not sure exactly how without more information.
Hope this is some help.

Categories