Resolved Get data from multiple sources?

bondra

Well-known member
Joined
Oct 24, 2020
Messages
77
Programming Experience
Beginner
I'm trying to get data from two lists/sources to populate my datagrid view. I manage to print all fields for an animal but the list of Toys. How can I proceed with this one? What's the correct route?

This is what my code looks like:
C#:
            Petowner.Pets.Add(new Cat
            {
                Name = "Kissise",
                Age = 3,
                FavFood = "Whiskas",
                Breed = "Ragdoll",
                IsHungry = true,
               // How can this list be printed as well?
                Toys =
               new List<Toy> {
                    new Bone {Size ="Large", Quality = 1},
                }
            });

name.jpg



What the code looks like to get the animals
C#:
dataGridView1.DataSource = Petowner.Pets;

And the class and properties from which fields are retrieved from:
C#:
abstract class Animal
    {
        // Properties
        public string Name { get; set; }
        public virtual int Age { get; set; }
        public string FavFood { get; set; }
        public string AnimalType
        public string FavFood { get; set; }
        public string Breed { get; set; }
        public bool IsHungry { get; set; }
        public List<Toy> Toys { get; set; } = new List<Toy>(); // How can this be added as well?
}

Fields from source that shows up:
1612732749717.png
 
Last edited:
Given that Toys is itself a list, how exactly would you expect it to be displayed in a single cell? The best you could hope for is for its ToString method to be called to produce a single String, but the result of that is not going to be useful to you. You could implement your own custom collection that does produce something useful with its ToString method and use that instead of the standard List<T>. Not sure whether you'd be able to bind to that the way you're trying to but there's only one way to find out. If you can't, there may still be another way to do it.

The alternative is to use two grids and filter the child data based on the parent selection.
 
Hmm are there other ways? This is how it's formated in my console application and prefered way to be displayed in my windows form app. Can the code be reused from the console app?
 
Hmm are there other ways?
Of course.
This is how it's formated in my console application and prefered way to be displayed in my windows form app.
You show us nothing and then tell us that that's how it is elsewhere. What does that mean to us?
Can the code be reused from the console app?
How exactly would I know that, given that I have never seen that code and don't know what it does?

It's a waste of my time to have to reply to posts like this. Please think about what you post and assume that we only know what you tell us, because that's the way it is.
 
How can I proceed with this one? What's the correct route?
The correct route is to implement a "view model" which presents a flat object with the columns that you want to present. The DataGridView cannot magically discern what columns that you want to be shown. It's "autogenerate" feature can only guess at the columns based on the public properties of the top level object.

Stop and think about it. For example, you had this class:
C#:
class Person
{
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
}

The DataGridView would just present two columns: Name and BirthDate. It doesn't really go digging into the DateTime and pull out other columns like Month, Day, Year, Hour, Minute, Seconds, and Milliseconds. Why would you expect the DataGridView to go digging into your Toy class to show the various properties of the Toy?

If I wanted to surface those extra columns, I would create a Person view model. Something like:
C#:
class PersonViewModel
{
    Person _person;

    public PersonViewModel(Person person) => _person = person;

    public string Name => _person.Name;
    public int Year => _person.BirthDate.Year;
    public int Month => _person.BirthDate.Month;
    public int Day => _person.BirthDate.Day;
}
 
Last edited:
The outcome I manage to put togheter was this which works fine.

C#:
public UserControlPlayAnimal()
        {
            InitializeComponent();

            dt.Columns.Add("Namn", typeof(string));
            dt.Columns.Add("Leksak", typeof(string));
            dt.Columns.Add("Storlek", typeof(string));
            dt.Columns.Add("Kvalité", typeof(string));
            dt.Columns.Add("Färg", typeof(string));

            foreach (var animal in Petowner.Pets)
            {
                foreach (var toy in animal.Toys)
                {
                    dt.Rows.Add(new object[] {
                    animal.Name,
                    toy.Name,
                    toy.Size,
                    toy.Quality,
                    toy.Color

                });
                }
            }
            dataGridView1.DataSource = dt;

        }
 
Back
Top Bottom