Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying a list of object containing a list in a grid view

I am currently working on a bookmark manager application (Windows Forms), with advanced search capabilities.

I have created a Links class, and every time a user enters a URL, I'll create a Link object and store the details there. It currently has the properties Name, URL and Tags, where Tags is a list.

At runtime when I set the DataSource property of a gridview to the List<Links> objects, the Name and the URL show up but the tags do not.

How do I go about displaying the list of tags inside the List<Links> object in the gridview?

EDIT: Just had an idea. What if I write a function to convert the List<Links> into a DataTable, and then set the DataSource property of the DataGrid to the DataTable?

The problem with this is that everytime a change is made to the List<Links> I will have to generate the DataTable again, which does not seem ideal from a performance point of view.

EDIT 2: I wish to display each item in the list as a DataGridViewTextBox column.

Thanks,

Abijeet.

like image 408
Abijeet Patro Avatar asked Oct 25 '12 08:10

Abijeet Patro


1 Answers

Maybe this is what you want... an object that appears to have more properties that it actually has.

The DataGridView controll supports the ComponentModel namespace so that you can create classes that appear to have properties that don't exist. It is the same mechanism the PropertyGrid uses.

Sample code

This sample is a fully working windows forms class, with a form containing a DataGridView. I add some objects to is, using a list that is then set to the DataSource property.

The objects inside that list, have no properties at all... but they use component model to describe 'virtual' properties to the DataGridView.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            this.dataGridView1.Dock = DockStyle.Fill;
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            dataGridView1.DataSource = new List<MyClass>
                    {
                      new MyClass("value 1", "value 2", "value 3"),
                      new MyClass("value 1", "value 2"),
                    };
        }

        class MyClass : CustomTypeDescriptor
        {
            public MyClass(params string[] tags)
            {
                this.tags = new List<string>(tags);
            }

            public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
            {
                var listProps = new List<PropertyDescriptor>();

                // adding properties dynamically
                for (int i = 0; i < tags.Count; i++)
                    listProps.Add(new PropDesc("Tag" + i, i));

                return new PropertyDescriptorCollection(listProps.ToArray());
            }

            private List<string> tags = new List<string>();

            class PropDesc : PropertyDescriptor
            {
                private int index;

                public PropDesc(string propName, int index)
                    : base(propName, new Attribute[0])
                {
                    this.index = index;
                }

                public override bool CanResetValue(object component) { return false; }

                public override Type ComponentType { get { return typeof(MyClass); } }

                public override object GetValue(object component)
                {
                    if (index >= ((MyClass)component).tags.Count)
                        return null;

                    return ((MyClass)component).tags[index];
                }

                public override bool IsReadOnly { get { return true; } }

                public override Type PropertyType { get { return typeof(string); } }

                public override void ResetValue(object component) { }

                public override void SetValue(object component, object value) { }

                public override bool ShouldSerializeValue(object component) { return false; }
            }
        }

        private void InitializeComponent()
        {
            this.dataGridView1 = new DataGridView();
            ((ISupportInitialize)(this.dataGridView1)).BeginInit();
            this.SuspendLayout();
            // dataGridView1
            this.dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView1.Dock = DockStyle.Fill;
            this.dataGridView1.Location = new System.Drawing.Point(0, 0);
            this.dataGridView1.Name = "dataGridView1";
            this.dataGridView1.Size = new System.Drawing.Size(284, 262);
            this.dataGridView1.TabIndex = 1;
            // Form1
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 262);
            this.Controls.Add(this.dataGridView1);
            this.Name = "Form1";
            this.Text = "Form1";
            ((ISupportInitialize)(this.dataGridView1)).EndInit();
            this.ResumeLayout(false);

        }

        private DataGridView dataGridView1;
    }
}
like image 70
Miguel Angelo Avatar answered Oct 04 '22 10:10

Miguel Angelo