Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / March 2008

Tip: Looking for answers? Try searching our database.

Retrieving items from a List<t>

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
John - 11 Mar 2008 22:52 GMT
Does anyone know how to retrieve the items from a List<T>
once you put the items in the list?

I have the following code

Lasse,

Actually that is what I was going to do until the other option
were laid out on the table for me.  I am trying to use list right
now.  I have run into a few issues so far.

//This is my class:
       public class Person
       {
           public string Name;
           public string Address;
           public string Phone;
           public Person(string name, string address, string phone)
           {
               this.Name = name;
               this.Address = address;
               this.Phone = phone;
           }
       }

// apply info to the list and assign it to the nodes tag property of
treenode
       private void button4_Click(object sender, EventArgs e)
       {
           if (treeView1.SelectedNode == null)
               return;

           List<Person> people = new List<Person>();
           people.Add(new Person(textBox1.Text, textBox2.Text,
textBox3.Text));
           treeView1.SelectedNode.Tag = people;
       }

// How do I get the information back from the tag?  I want to display it in
a listview.
// this doesn't work.

       private void treeView1_Click(object sender, EventArgs e)
       {
           listView1.BeginUpdate();
           listView1.Items.Clear();
           List<Person> people = new List<Person>();
           people.ForEach(delegate(Person p)
           {
               ListViewItem item1 = new ListViewItem(p.name, 0);
               item1.SubItems.Add(p.address);
               item1.SubItems.Add(p.phone);
               listView1.Items.Add(item1);
           });
           listView1.EndUpdate();
       }

All I need is an example of storing and retrieving the data from different
parts
of the program.

Thank you
Mattias Sjögren - 11 Mar 2008 23:05 GMT
>// How do I get the information back from the tag?  I want to display it in
>a listview.
[quoted text clipped - 5 lines]
>            listView1.Items.Clear();
>            List<Person> people = new List<Person>();

I think what you want is

List<Person> people = treeView1.SelectedNode.Tag as List<Person>;

Mattias

Signature

Mattias Sjögren [C# MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Peter Duniho - 11 Mar 2008 23:16 GMT
> I think what you want is
>
> List<Person> people = treeView1.SelectedNode.Tag as List<Person>;

Not unless he's going to check to see if "people" winds up being null, and  
handling that gracefully.

Otherwise, a straight cast is more appropriate.

Pete
Peter Duniho - 11 Mar 2008 23:12 GMT
> Does anyone know how to retrieve the items from a List<T>
> once you put the items in the list?

Yes.  Just use the indexer on the class (e.g. "list[10]") or enumerate the  
elements (e.g. "foreach (Person person in list)"), or any of the other  
methods defined on the List<T> class that retrieve items.

But based on the code you posted, that doesn't really seem to be your  
actual question.

> [...]
> // How do I get the information back from the tag?  I want to display it  
> in a listview.

You need to cast the Tag property back to List<Person>.

> // this doesn't work.
>
[quoted text clipped - 3 lines]
>             listView1.Items.Clear();
>             List<Person> people = new List<Person>();

In the line above, you are creating a new List<Person>.  That's not going  
to help you get things from the List<Person> you created earlier.

>             people.ForEach(delegate(Person p)
>             {
[quoted text clipped - 3 lines]
>                 listView1.Items.Add(item1);
>             });

While I love anonymous methods as much as the next guy, if not more, I'm  
not really sure what value is added here by using one.

I think what you really want is code that looks something like this:

    foreach (Person person in (List<Person>)treeView1.SelectedNode.Tag)
    {
        ListViewItem item1 = new ListViewItem(person.name, 0);

        item1.SubItems.Add(person.address);
        item1.SubItems.Add(person.phone);
        listView1.Items.Add(item1);
    }

> All I need is an example of storing and retrieving the data from  
> different
> parts of the program.

Using the Tag property is one way to do this, as demonstrated by your  
example and the changes above to make it work.  However, I think it's  
worth keeping in mind that it's not always the best way.  One thing I  
notice about this is that your code is completely dependent on the order  
in which the user does things.  They first have to initialize a hidden  
state in the TreeView instance, which is then read later to initialize the  
ListView instance.

IMHO, I think a better paradigm would be for the controls to always be  
linked in the first place so that changes in the source data and in the  
selected node of the TreeView are automatically reflected in the  
ListView.  I realize this doesn't have anything to do with your original  
question, but I think it's worth mentioning and worth your time to  
consider.

Pete
John - 12 Mar 2008 00:03 GMT
Pete,

This sounds like a good idea, but I am not really following code wise on
what you
are saying.  Link the treenode to the listview, I thought that is what I was
doing by
storing the information for the listview into each treenode.

Can you elaborate a bit more, perhaps a simple example.

I thought I had the right idea the other day by using an array, then it was
pointed
out to me to use the List<T> which is a lot better since I can add, delete
and modify
the items in the list.

Your idea I would like to try too since it sounds really good, but I am not
following so far
on how to do that.

John

IMHO, I think a better paradigm would be for the controls to always be
linked in the first place so that changes in the source data and in the
selected node of the TreeView are automatically reflected in the
ListView.  I realize this doesn't have anything to do with your original
question, but I think it's worth mentioning and worth your time to
consider.

Pete
Peter Duniho - 12 Mar 2008 02:57 GMT
> Pete,
>
[quoted text clipped - 3 lines]
> was doing by
> storing the information for the listview into each treenode.

You are, sort of.  It's how integrated the UI is with changes to the  
data.  Specifically, when you add a new element to the List<Person>,  
there's no code that updates the ListView to represent that change.  Also,  
you only update the ListView in response to actual Click events in the  
TreeView, but there are other ways for the selected node to change.

It's my opinion that it would be better to keep the ListView more tightly  
connected to the state of the TreeView than that.

You could take it one step further and separate your data from the GUI  
even more, using a BindingList<Person> instead, which provides events to  
detect changes to the list.  Then the ListView could just be bound to the  
current BindingList<Person> (which would change according to the TreeView  
selection), and as that list changes contents, or a new list is assigned  
as the current list for the ListView, the ListView would update  
automatically.

One last thing: the example of code I posted was for the updating of the  
ListView, of course.  You would also need to do the symmetric thing in the  
"button4_Click" method.  Instead of always instantiating a List<Person>  
there, you need to get the current value of the treeView1.SelectedNode.Tag  
property, and if it's null, create a new List<Person> to use and assign  
that to the Tag property, but otherwise use the instance that's already  
set there.

Or you could just always create the List<Person> when you create the node  
itself.  But either way, you need to make sure there's just the one  
List<Person> associated with the node all the time, and that rather than  
overwriting a previous List<Person> instance for the node, you just use  
whatever's already there.

Pete
John - 12 Mar 2008 03:12 GMT
Hi Pete,

> You could take it one step further and separate your data from the GUI
> even more, using a BindingList<Person> instead, which provides events to
> detect changes to the list.  Then the ListView could just be bound to the
> current BindingList<Person> (which would change according to the TreeView

Is this difficult to do?  I understand what you are saying, but I have never
had
to do anything like that before.  So that leaves me as how do you do it?
I just need a head start.

> selection), and as that list changes contents, or a new list is assigned
> as the current list for the ListView, the ListView would update
> automatically.

I am looking forward in seeing how this is actually done.  If you can
provide
an example, make it simple so I can follow what's going on, it will be
greatly
appreciated and I will be on my way with this.

Thank you Pete.

John
Peter Duniho - 12 Mar 2008 05:28 GMT
> Hi Pete,
>
[quoted text clipped - 9 lines]
> to do anything like that before.  So that leaves me as how do you do it?
> I just need a head start.

Well, maybe it'd be better to start with the more basic suggestion I  
offered.  Especially since I'm doing a little hand-waving above.  I know  
that binding should be possible, but I don't actually use binding myself  
that often and I'm not entirely clear on how binding with ListView would  
work (with simpler controls, in which there's a simple display of a list  
of text items, it's very straight-forward...for example, in ListBox, just  
set the DataSource property, and it does the right thing, assuming your  
class overrides ToString() in a useful way).

Even using binding, you'll have to react to changes in the selection,  
which is demonstrated in this example illustrating the simpler  
suggestion.  The main difference between this example and the code you  
posted is that the ListView always stays current with whatever is going on  
in the TreeView.

Marc Gravell has helped me out with binding questions in the past, so  
maybe he'll have some insight as to a specific technique that would hook  
up a BindingList<Person> with a ListView.  In the meantime, here's an  
example (see below) of doing a similar thing, but with a little more code  
(i.e. it's more explicit, because it's not using binding).

Pete

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TestBindingListView
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    public class Form1 : Form
    {
        private struct ItemData
        {
            public readonly string Item;
            public readonly string Details;

            public ItemData(string item, string details)
            {
                Item = item;
                Details = details;
            }
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            TreeNodeCollection nodes = treeView1.SelectedNode != null ?
                treeView1.SelectedNode.Nodes : treeView1.Nodes;

            nodes.Add(textBox1.Text);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            TreeNode node = treeView1.SelectedNode;

            if (node != null)
            {
                List<ItemData> rgid = (List<ItemData>)node.Tag;

                if (rgid == null)
                {
                    rgid = new List<ItemData>();
                    node.Tag = rgid;
                }

                rgid.Add(new ItemData(node.Text, textBox2.Text));
                _UpdateListView(rgid);
            }
        }

        private void _UpdateListView(List<ItemData> rgid)
        {
            listView1.Items.Clear();

            if (rgid != null)
            {
                foreach (ItemData id in rgid)
                {
                    ListViewItem lvi = new ListViewItem(id.Item);

                    lvi.SubItems.Add(id.Details);
                    listView1.Items.Add(lvi);
                }
            }
        }

        private void treeView1_AfterSelect(object sender,  
TreeViewEventArgs e)
        {
            TreeNode node = treeView1.SelectedNode;

            if (node != null)
            {
                _UpdateListView((List<ItemData>)node.Tag);
            }
            else
            {
                _UpdateListView(null);
            }
        }

        private void treeView1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                treeView1.SelectedNode = null;
                e.Handled = true;
            }
        }

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be  
disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.treeView1 = new System.Windows.Forms.TreeView();
            this.listView1 = new System.Windows.Forms.ListView();
            this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
            this.button2 = new System.Windows.Forms.Button();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            //
            // button1
            //
            this.button1.Location = new System.Drawing.Point(13, 13);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(96, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "New Tree Node";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new  
System.EventHandler(this.button1_Click);
            //
            // textBox1
            //
            this.textBox1.Location = new System.Drawing.Point(115, 15);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 20);
            this.textBox1.TabIndex = 1;
            //
            // treeView1
            //
            this.treeView1.Anchor =  
((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top  
| System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.treeView1.Location = new System.Drawing.Point(13, 43);
            this.treeView1.Name = "treeView1";
            this.treeView1.Size = new System.Drawing.Size(292, 257);
            this.treeView1.TabIndex = 2;
            this.treeView1.AfterSelect += new  
System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
            this.treeView1.KeyDown += new  
System.Windows.Forms.KeyEventHandler(this.treeView1_KeyDown);
            //
            // listView1
            //
            this.listView1.Anchor =  
((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top  
| System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.listView1.Columns.AddRange(new  
System.Windows.Forms.ColumnHeader[] {
            this.columnHeader1,
            this.columnHeader2});
            this.listView1.Location = new System.Drawing.Point(311, 43);
            this.listView1.Name = "listView1";
            this.listView1.Size = new System.Drawing.Size(174, 257);
            this.listView1.TabIndex = 3;
            this.listView1.UseCompatibleStateImageBehavior = false;
            this.listView1.View = System.Windows.Forms.View.Details;
            //
            // columnHeader1
            //
            this.columnHeader1.Text = "Item";
            //
            // columnHeader2
            //
            this.columnHeader2.Text = "Description";
            this.columnHeader2.Width = 108;
            //
            // button2
            //
            this.button2.Location = new System.Drawing.Point(311, 13);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(64, 23);
            this.button2.TabIndex = 4;
            this.button2.Text = "New Item";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new  
System.EventHandler(this.button2_Click);
            //
            // textBox2
            //
            this.textBox2.Location = new System.Drawing.Point(381, 15);
            this.textBox2.Name = "textBox2";
            this.textBox2.Size = new System.Drawing.Size(104, 20);
            this.textBox2.TabIndex = 5;
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(497, 312);
            this.Controls.Add(this.textBox2);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.listView1);
            this.Controls.Add(this.treeView1);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.TreeView treeView1;
        private System.Windows.Forms.ListView listView1;
        private System.Windows.Forms.ColumnHeader columnHeader1;
        private System.Windows.Forms.ColumnHeader columnHeader2;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.TextBox textBox2;
    }
}
John - 12 Mar 2008 13:25 GMT
Thank you very much Pete.  I see in your code you took
into consideration a few different events, that in itself
teaches me a few different things in handling some of
these events.

I do appreciate this example code. I am going to try it out
and hopefully I can advance a bit in doing some more
advanced stuff.

Thanks again

John
John - 12 Mar 2008 15:30 GMT
Pete,

I just tried the sample you posted and it works great.

Thanks again for your help.

John

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.