VS 2010 Report Viewer Cannot Access Nested Collections, Anyone? - c#

I have gone through all the walk through on MSDN as usual they are worthless - extremely limited.
If I make the internal object in my class a single class I can display the information, but as soon as I convert it to a list of objects ( a collection ) I get the #Error in the display.
Here is an updated example.
For an example I have a Person object that can have one or more phone numbers ( list of numbers ) and I cannot find a way to access the phone numbers.
[Serializable]
public class Person
{
private readonly List<PhoneNumber> _numbers = new List<PhoneNumber>();
public Person()
{
}
public Person(int id, string name, string address, decimal salary)
{
Id = id;
Name = name;
Address = address;
Salary = salary;
}
public void AddNumber(PhoneNumber number)
{
_numbers.Add(number);
}
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public List<PhoneNumber> PhoneNumbers { get { return _numbers; } }
}
[Serializable]
public class PhoneNumber
{
public PhoneNumber()
{
}
public PhoneNumber(int id, string areaCode, string phone)
{
AreaCode = areaCode;
Id = id;
Phone = phone;
}
public string AreaCode { get; set; }
public string Phone { get; set; }
public int Id { get; set; }
}
I then populate the collections.
var persons = new List<Person>();
var t = new Person(1, "Mike", "5150 Nuts", 125);
t.AddNumber(new PhoneNumber(1, "425", "455"));
t.AddNumber(new PhoneNumber(1, "425", "450"));
persons.Add(t);
t = new Person(2, "Tom", "1055 MS HAS NO DOCUMENTATION AS USUAL!", 1245);
t.AddNumber(new PhoneNumber(2, "TYPICAL", "OF-THEM"));
t.AddNumber(new PhoneNumber(2, "ANY", "ONE???"));
persons.Add(t);
I then assign everything to the report.
reportViewer1.ProcessingMode = ProcessingMode.Local;
reportViewer1.LocalReport.ReportPath = "..\\..\\Report1.rdlc";
reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("Person",persons));
reportViewer1.RefreshReport();
In the report it displays the people will display without issue as I add the text boxes to a list and then group the list by Id. When I try to display the phone numbers, I get the #ERROR message, and for the life of me I cannot seem to find a way to display the list of numbers that are assigned to a person.
If I change the object from List<PhoneNumber> within the person class to PhoneNumber I can access it, but when trying to display a List<PhoneNumber> I cant.
I need to be ale to display List<of objects> within an Class Item.

The nested collection must be displayed as a subreport where the nested collection is an separate data source. You must bind the event LocalReport.SubreportProcessing to a handler that will filter and bind the datasource (PhoneNumbers) to the subreport as a seperate report data source. The example at the link provided should get you where you need to go.

Related

Class including list

when i am assigning the values in the list its saying object not set to instance of an object any help , i can retrieve from other service , when i am trying to assign the value in the list its creating problem
public class exam
{
public string Name { get; set; }
public string Age { get; set; }
public string RollNo { get; set; }
public List<Subject> subject{get; set;}
}
public class Subject
{
public string SubjectName{ get; set;}
public string SubjectPartNo{ get; set; }
}
exam ex = new exam()
ex.Name = "john"
ex.Age = 22
ex.RollNo = 13
ex.subject.SubjectName = "English"
ex.subject.SubjectPartNo = 1
subject is an object which is defined as a list of type Subject. Like every other object this needs to first be instantiated before it can be used. The fact that it is inside Exam (another object) doesn't change this.
So you can do this either during property assignment like this.
public List<Subject> subject { get; set; } = new List<Subject>();
or you can create a constructor and instantiate it there
public exam()
{
subject = new List<Subject>();
}
So now you have an empty list, that's the first part of the problem resolved. But you are still trying to assign values to it incorrectly.
subject is a list of Subject, so this means we can only add Subject objects to it.
First create a new Subject object and add values to it. (can also be done inline). Here we create two;
Subject sub1 = new Subject();
sub1.SubjectName = "English";
sub1.SubjectPartNo = "1";
Subject sub2 = new Subject();
sub2.SubjectName = "Maths";
sub2.SubjectPartNo = "2";
Then add these to your list;
exam ex = new exam();
ex.Name = "john"
ex.Age = "22";
ex.RollNo = "13";
ex.subject.Add(sub1);
ex.subject.Add(sub2);
Now you have an exam object with 2 Subjects
BTW: You have many properties, such as age, which are defined as string but you are trying to add integer values to them. They need to be correctly defined according to the right datatype. Don't just set everything to string because it is "easier" now, it will cause you problems later.

Is it normal to have a list of objects in an object?

I'm new to OO design, and I wondering whether it is typical to have designs where objects contain lists of other objects. An example is below:
// Person object containing a list of phone numbers
public class Person
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Phone> Contacts { get; set; }
public void AddPhoneNumber(Phone phone)
{
Contacts.Add(phoneNumber);
}
}
// Phone object
public class Phone
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Number { get; set; }
}
// Example code to establish an object:
Person p1 = new Person();
p1.FirstName = "John";
p1.LastName = "Smith";
p1.AddPhoneNumber(new Phone() { Number = "555957000" });
p1.AddPhoneNumber(new Phone() { Number = "555579561" });
Is there a better way to structure this that simplifies the design and allows easier access to the data? Thanks!
Yes, it is absolutely fine to have an object contains list of object. In OOPs this is called Composition, which represent strong relationship between participating class.
I wondering whether it is typical to have designs where objects
contain lists of other objects.
Absolutely, this is normal as an object can contain lists that belong to only that particular object. One of many examples is when you're traversing a binary tree or such you could have each node have their own list which identifies their children. There are many more cases in which an object should/could contain their own list.
Going back to your code, you seem to have an error because the code below states that the list will contain Phone objects.
public List<Phone> Contacts { get; set; }
but yet you're passing in a string object rather than a phone object.
public void AddPhoneNumber(string phoneNumber)
{
Contacts.Add(phoneNumber); // this code shouldnt compile
}
rather what you can do is this:
public void AddPhoneNumber(string phoneNumber)
{
Contacts.Add(new Phone() { Number = phoneNumber });
}
There's nothing wrong with your code. It's perfectly valid to have a list of objects within an object.
Though adding a string to your List of Phone objects will throw an error.
You can add a phone number like so:
Person p1 = new Person();
p1.Contacts.Add(new Phone() { Number = "555579561" });

Creating a List of Classes that contains a List of a Class

I'm studying C# Classes and am trying to create a program that has a Class called Employee and derived classes of ProductionWorker, ShiftSupervisor, and TeamLeader.
I have a list box where I want to display All the employees, and within the program, there's functionality to add, edit, or remove respective people, but rather than making 3 lists like so:
List<ProductionWorkers> pWorkers = new List<ProductionWorkers>();
List<ShiftSupervisor> sSupervisors = new List<ShiftSupervisor>();
List<TeamLeader> tLeaders = new List<TeamLeader>();
I'd like to be able to have the Employee base class have or contain some sort of list of it's derived classes and their objects.
For example I'd like to be able to be able to Add and Remove derived objects to a list of Employees in some fashion, given the following example:
List<Employee> employees = new List<Employee>();
ProductionWorker _pWorker = new ProductionWorker();
_pWorker.Name = "Bob";
_pWorker.EmployeeID = 1234;
employees.Add(_pWorker));
I don't know if that's even possible or realistic to do that, but it would seem maybe there is a way from what I've read, I'm just not sure how to implement it. I'm open to better suggestions however, if someone knows of a better or proper way to get all the Employees listed into a ListBox without having to cycle through 3 different lists of the different derived classes.
For clarity, below is the Base class, then its following derived classes.
public class Employee
{
public string Name { get; set; }
public int EmployeeNumber { get; set; }
}
class ProductionWorker : Employee
{
public int ShiftNumber { get; set; }
public decimal HourlyPayRate { get; set; }
}
class TeamLeader : ProductionWorker
{
public int ReqHours { get; set; }
public int AttendedHours { get; set; }
}
class ShiftSupervisor : Employee
{
public int Salary { get; set; }
public int AnnualProductionBonus { get; set; }
}
I didn't realize until I posted my classes here that Team Leader is actually a derived class of Production Worker. I'm not sure if that changes things...
Yes, you can add Employee items and items deriving from Employee to the employees list.
List<Employee> employees = new List<Employee>();
ProductionWorker pWorker = new ProductionWorker {
Name = "Bob",
EmployeeID = 1234
};
employees.Add(pWorker);
If you want to display all these different kinds of employees in the same listbox, override the ToString method in these classes. The ListBox will automatically use it in order to display the items.
public class ProductionWorker : Employee
{
public override string ToString()
{
return String.Format("{0} ({1}), production", Name, EmployeeID);
}
}
You can assign the list of employees to the listbox like this
employeeListBox.DataSource = employees;
From the employees list you can access the members declared in Employee directly:
int id = employees[i].EmployeeID;
However; you need to cast, if you want to access members of derived types
int salary = 0;
var supervisor = employees[i] as ShiftSupervisor;
if (supervisor != null) {
salary = supervisor.Salary;
}
If you know the type of an item in advance you can cast directly
int salary = ((ShiftSupervisor)employees[0]).Salary;

Creating custom linq column names in list

We are returning a generic List to a GridView, which then auto generates columns to show a report:
//Generate List
List<Stock> allStock = blStock_Collection.getAll();
//export custom view for report datagrid
return (from myStock in allStock
select new
{
myStock.Category,
myStock.Description,
myLowStock.UnitPrice,
myLowStock.CurrentQuantity
});
Our client has asked that we now provide multi-lingual support on our site (English & Polish), specifically the column headers on grids. We would therefore need to get rid of the auto generate option on all our data grids, and add in the translations manually for each column.
I was wondering is there a way to do this when generating the datasource, which would save us a hell of a lot of time, e.g. changing this line:
myStock.Category,
to something like:
languagePack.Category = myStock.Category,
This is of course throwing a 'Invalid anonymous type member declarator' error. Any advice?
Maybe I misread something, but if you just want to put your language into it (LanguagePack is just a class holding your values):
class LanguagePack
{
public int Category { get; set; }
public string Description { get; set; }
public decimal UnitPrice { get; set; }
public int CurrentQuantity { get; set; }
public int LanguageName { get; set; }
}
return (from myStock in allStock
select new LanguagePack
{
Category = myStock.Category,
Description = myStock.Description,
UnitPrice = myLowStock.UnitPrice,
CurrentQuantity = myLowStock.CurrentQuantity,
LanguageName = "Polish" // or english or whatever... maybe LanguageId or something corresponding to your model
});

Using Array of Arrays for One to Many Relationship in C#

I am making a console test with C#.
Actually I have never used of C# but VB.Net. I want to create arrays for one-to-many relationship.
My one is 'A Student' has 'Name','Sex',...,'Courses Taken'.
A Student would take many course, each course has a Title and Included Subject. Each subject has Name, Description and Point.
Like this.
Student
- Name - Sex - Courses Taken
Take Courses
- Course Title - Subject Included
Subject
- Subject Name [Math] [MVC]
- Subject description [Advance] [Building Website]
- Subject Point [6.9] [5.6]
I want to store each entity in Arrays but I don't know how to connect subjects/courses to each Students. And how can I get Student who attending Math or MVC. Because every students can have more then more course/ more than one subjects.
You'll want to create classes to describe your different objects.
class Student
{
string Name { get; set; }
Gender Sex { get; set; } // write an enum for this
IEnumerable<Course> CoursesTaken { get; set; }
}
class Course
{
string Title { get; set; }
Subject Subject { get; set; }
}
class Subject
{
string Name { get; set; }
string Description { get; set; }
double Points { get; set; }
}
Using List to create enumerations of instances of these new types allow you to use LINQ to select or evaluate members of the list (nested for loops work as well):
// populate a list of students called studentList
//...
// use LINQ to select the students you want
var mathResults = studentList.Where(student => student.CoursesTaken.Any(course => course.Subject.Name == "Math"));
I feel like I've done with it in good way...
Pls check my code for my ques! ^^
I first made 3 classes as below..
class Students
{
public string StudentName;
public int StudSize;
public bool StudSex;
public List<Take_Courses> tcourses;
public Students() { }
public Students(string name, int size, bool sex, List<Take_Courses> tcourses)
{
StudentName = name;
StudSize = size;
StudSex = sex;
this.tcourses = tcourses;
}
}
and
class Take_Courses
{
public string classname;
public List<Arr_Courses> arr_Course;
public Take_Courses() { }
public Take_Courses(string classname, List<Arr_Courses> arr_courses)
{
this.classname = classname;
arr_Course = arr_courses;
}
}
class Arr_Courses
{
public string cosname;
public string cosdesc;
public float cospoint;
public Arr_Courses() { }
public Arr_Courses(string name, string description, float point)
{
cosname = name;
cosdesc = description;
cospoint = point;
}
}
I then initialized values in Main class as below;
Arr_Courses acos=new Arr_Courses();
Arr_Courses acos1=new Arr_Courses("Math","Advance Math1",9.5f);
Take_Courses cos=new Take_Courses();
Take_Courses cos_take1=new Take_Courses("Info Tech",new List<Arr_Courses>{acos1});
Students stu=new Students();
Students Stu1 = new Students("Milla", 22, true,new List<Take_Courses>{cos_take1});
I then make another List to be generated names of student and use for looping and assign each one to List.
I think some important part is this.
if (arr_stud[i].tcourses[j].arr_Course[k].cosname.Equals("Math"))
{
Math_Stud++;
MathStudents[i] = arr_stud[i];
}
I am sharing this if anyone needs something like this. Any ungraded codes is appreciated to be shared. Thanks so so.

Categories