Binding Complex Data source of a class into Grid View - c#

Here I have these Classes:
public class CustomerDebt
{
public int ID { get; set; }
public string Name { get; set; }
public string Family { get; set; }
public string Remain { get; set; }
public List<Shops> details = new List<Shops>();
}
public class Shops
{
public List<int> ints = new List<int>();
public List<string> strings = new List<string>();
}
I'm making a list of CustomerDebts objects:
List<CustomerDebt> debts = new List<CustomerDebt>();
and Here I will add one item to it:
Shops shop = new Shops();
shop.ints.Add(1);
shop.ints.Add(2);
shop.strings.Add("M");
shop.strings.Add("S");
shop.strings.Add("F");
CustomerDebt d = new CustomerDebt();
d.ID = 12;
d.Name = "Joe";
d.Family = "Steven";
d.Remain = "1000";
d.details.Add(shop);
debts.Add(d);
Now I bind debts list into a grid view:
gridview.DataSource = debts;
It will automatically fill the grid view with only "ID,Name,Family,Remain" properties of CustomerDebt Class. But I need to bind the List property which is a list of another Class into grid view.
I think it needs something like {get; set;} to be shown in grid, But also I do not know If the grid can show a nested class like this.
Hope I'm clear. What should I do to get a clean Grid view with such list of Class objects?

There is no built-in support for Master Details in the DataGridView Control in Windows Forms. But we have the option to use Third Party Libraries Like:
Telerik.
Devexpress.
As for the binding issue, yes you need to have a public property with a public getter:
public List<Shops> details { set; get; } = new List<Shops>();
For prior to C# 6 you can use:
public class CustomerDebt
{
public CustomerDebt()
{
details = new List<Shops>();
}
public List<Shops> details { set; get; }
}

Another way of doing this other than the accepted answer can be like below. Columns can be added manually and then the rows can be filled accordingly.
this.gridview.Columns.Add("ID", "ID");
this.gridview.Columns.Add("Name", "Name");
this.gridview.Columns.Add("Family", "Family");
this.gridview.Columns.Add("Remain", "Remain");
this.gridview.Columns.Add("Details", "Details");
foreach (var debt in debts)
foreach (var detail in debt.details)
this.dataGridView1.Rows.Add(debt.ID, debt.Name, debt.Family, debt.Remain, "Ints:" + string.Join(",", detail.ints) + " Strings:" + string.Join(",", detail.strings));

Related

Entity Framework NullReferenceException when accessing lists

I am using Windows Forms and I'm just learning Entity Framework and I have a question: I created a Customer class with a list type of Item and with Entity Framework I created a table for it. But when I try to get the list from it, I get a NullReference exception.
This are my classes:
public class Item
{
public int Id{ get; set; }
public string ItemName { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string UserName { get; set; }
public string PassWord { get; set; }
public List<Item> Items { get; set; }
}
And this is the method I created to get the customer list based on the ID of the customer. I get the Id from the login and it works just fine:
public List<Item> CustomerItems()
{
using var context = new CustomerContext();
var customer= context.Customers.Find(Id);
var items = customer.Items;
return items;
}
I wanted to use this method to update the datagrid and add new items to the list.
I added some entries to the Item table but they don't show up in the datagrid.
Please check the loading related data section of the docs for options how to load linked data.
Also in this case you can just use proper query returning only needed data. For example:
var items = context.Customers
.Where(c => c.Id == Id)
.SelectMany(c => c.Items)
.ToList();
In the code snippet presented above a NullReferenceExceptionmay occur in the access to Items in the expression customer.Items when customer is null. The code should be modified to handle the null value, e.g.
var items = (customer == null) ? new List<Item>() : customer.Items;

How to set DataGridView column header through a linq query?

I have an sql database for vehicle details. I want to display some fields of the linq query on a datagridview control with different column headers with spaces other than the database field names. I tried it as below but it gives an error. How do I do this?. Thank you guys.
var vlist = from lst in dc.tblVhcleInfos
select new {"Registration Number"= lst.RegNo, "Make and Model"=lst.makeModel, "Year of Manufacture"=lst.YOM};
dataGridView1.DataSource = vlist;
You cannot set up Custom names for Dynamic LINQ Classes, declare class first, add DisplayName attribute to properties, like this
// Define new Class
public class VhcleInfo
{
[DisplayName("Registration Number")
public string RegNo { get; set; }
[DisplayName("Make and Model")
public string MakeModel {get; set; }
[DisplayName("Year of Manufacture")
public int Year { get; set; }
}
// Create IEnum for Defined Class
var vlist = from lst in dc.tblVhcleInfos
select new VhcleInfo() { RegNo = lst.RegNo, MakeModel = lst.makeModel, Year = lst.YOM };
// Set Data Source
dataGridView1.DataSource = vlist;

Remove columns from list object out of a class c#

I need the possiblity to create Code in C# like this
public class SummaryA
{
public string name { get; set; }
public string surename { get: set; }
public int age { get; set;}
}
now I create an list object from the class SummaryA
List<SummaryA> list1= new List<SummaryA>();
yet I need the possibility to remove the column age from the list Summary, anyone have ideas?
I need this for some more columns, so I wish the list was dynamically or some things else.
sry for my bad english.
To completely remove the column you really need another class to store the data in, for example:
public class AgelessSummaryA
{
public string name { get; set; }
public string surename { get: set; }
}
And now you can project the first list into a new list of this class with Linq and Select:
List<AgelessSummaryA> agelessSummaries = ageSummaries
.Select(s => new AgelessSummaryA
{
name = s.name,
surename = s.surename
})
.ToList();
To use it for in a grid or for some display i guess, then you can use anonymous types where you can shape the data the way you like:
var projectedList = (from l in list1
select new
{
name = l.name,
surename = l.surename
}).ToList();

How to convert data row to custom model

I have a custom model like this:
public class VoteOptionModel
{
public List<int> Index { get; set; }
public List<string> Description { get; set; }
}
And i have a method returns me a datatable.I want to bind database values to my custom model.
var filed1= dt.AsEnumerable().Select(s => s.Field<int>("field1")).ToList();
var field2= dt.AsEnumerable().Select(s => s.Field<string("field2")).ToList();
VoteOptionModel model= new VoteOptionModel();
model.Index = visindex;
model.Description = description;
That code is ok but i'm wondering if there is a "better" way. Can we use AsEnumarable() method?
dt.AsEnumarable().Select(r=>new VoteOptionModel{Index=r["filed1"].toList()}); or sth.
You can gather all aggregated data in one run (make sure you initialize lists in model constructor) with Enumerable.Aggregate:
var model = dt.AsEnumerable().Aggregate(new VoteOptionModel(),
(model,r) => {
model.Index.Add(r.Field<int>("field1"));
model.Description.Add(r.Field<string>("field2"));
return model;
});
If you don't want to change model's constructor, then initialize model this way:
new VoteOptionModel() {
Index = new List<int>(),
Description = new List<string>()
}
But I would suggest to have list of models instead of aggregated model, thus you have pairs of index and description values which are strongly related to each other:
public class VoteOptionModel
{
public int Index { get; set; }
public string Description { get; set; }
}
And getting them this way:
var models = dt.AsEnumerable().Select(r => new VoteOptionModel {
Index = r.Field<int>("field1"),
Description = r.Field<string>("field2")
}).ToList();

How to selectively display and not display column of object in BindingList which is bond to gridcontrol of devexpress winform?

Dear all devexpress winform gurus:)
My way is simple. First, i create a bindinglist:
private BindingList<QuoteOnGrid> quoteOnGrids = new BindingList<QuoteOnGrid>();
Then my object called quote will be added to the BindingList above, the quote have multiple properties and will be displayed on the grid after binding code below:
gridControl1.DataSource = quoteOnGrids;
The picture below show how manually remove column
a busy cat http://i.minus.com/i1JuwLqAdWy2K.jpg
How could I disable the displaying of last three property of these financial quote object without removing these properties?:)
Thanks in advance!
Please use the GridColumn.Visible property:
//...
gridControl1.DataSource = new BindingList<Person>();
gridView1.Columns["ID"].Visible = false;
}
//...
class Person {
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}

Categories

Resources