Click here to Skip to main content
15,886,689 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi,

I have a Windows forms project with 2 tabs. Both tabs have a ListView control. The first tab shows the contents of one folder (Checked Out) and the other contains the contents of another folder (checked in).

Despite my limited knowledge of c# (still learning) i've managed to make both ListView controls behave pretty much as i want them too.

However, what i need to be able to do, is when i click the 'Check Out' button on tab 1, the selected files in the listView1 control are removed (along with the file in the checked in folder being moved to the checked out folder). Then the listView2 in the second tab should display the files that were moved. This, somewhat surprisingly, i have managed to do with some success.

My first problem is that the listview2 in the second tab doesn't automatically refresh - so i effectively have to close the program and re-open it in order to see the updated listView2 with the new files.

My second problem (and this has been doing my head in for hours) is this: I have 4 columns in my ListViews (name, size, date modified and notes). The first 3 colums come accross into my listView2 control without problem (because i'm not copying from one list to the other, the lists are just looking at a folder containing files - and the files are movin from one to the other). However, what i need is for the 'Notes' data which is stored in column 4 (index 3) in listView1 to come accross into listView2 when the data moves accross.

I hope that's clear enough. Basically i don't know how to copy the column 4 data of one listView to column 4 of the other Listview.

Any pointers would be greatly appreciated.

Please see my code (some previous attempts have been commented out). (Also, i know the code isn't very efficient ... i intend to clean it up later, but i'm always open to suggestions on improving my code).

001	// ListView1
002	            string[] checkedINfileList = Directory.GetFiles("O:\\TestDaws\\CSDB\\CheckedIN");
003	 
004	 
005	            foreach (string file in checkedINfileList)
006	            {
007	                FileInfo f = new FileInfo(file);
008	 
009	                long fileSize = f.Length;
010	                DateTime file_date = f.LastWriteTime;
011	                string fileName = Path.GetFileName(file);
012	 
013	                ListViewItem item = new ListViewItem(fileName);
014	 
015	                listView1.Items.Add(item);
016	                item.SubItems.Add(fileSize.ToString() + " Kb");
017	                item.SubItems.Add(file_date.ToString());
018	 
019	            }
020	            //ListView2
021	            string[] checkedOUTfileList = Directory.GetFiles("O:\\TestDaws\\CSDB\\CheckedOUT");
022	 
023	 
024	            foreach (string file in checkedOUTfileList)
025	            {
026	                FileInfo f = new FileInfo(file);
027	 
028	                long fileSize = f.Length;
029	                DateTime file_date = f.LastWriteTime;
030	                string fileName = Path.GetFileName(file);
031	 
032	                ListViewItem item2 = new ListViewItem(fileName);
033	 
034	                listView2.Items.Add(item2);
035	                item2.SubItems.Add(fileSize.ToString() + " Kb");
036	                item2.SubItems.Add(file_date.ToString());
037	 
038	 
039	 
040	                //NEED TO ADD THE VALUE STORED IN THE 4TH COLUMN (POS 3) OF LISTVIEW1 IN HERE
041	                //THE 4TH COLUMN IS POPULATED FURTHER DOWN THE CODE WITH THE BUTTON_2 CLICK EVEN HANDLER
042	 
043	                 
044	                 
045	            }
046	              
047	        }
048	 
049	 
050	       //Check Out Button Click
051	        public ListView.SelectedListViewItemCollection mySelectedItems;
052	 
053	        private void button1_Click(object sender, EventArgs e)
054	        {
055	            mySelectedItems = listView1.SelectedItems;
056	 
057	            string toDir ="O:\\TestDaws\\CSDB\\CheckedOUT";
058	            string fromDir = "O:\\TestDaws\\CSDB\\CheckedIN";
059	 
060	            if (mySelectedItems.Count > 0)
061	                 
062	            {
063	                foreach (ListViewItem items in mySelectedItems)
064	                {
065	                    try
066	                    {
067	                        File.Move(fromDir + "\\" + items.Text, toDir +"\\" + items.Text);
068	                        MessageBox.Show("Checking Out: \n" + items.Text);
069	                        listView2.Refresh();
070	 
071	                     
072	 
073	                        //for (int i = 0; i < listView1.Items.Count; i++)
074	                        //{
075	 
076	                        //    ListViewItem newList = new ListViewItem();
077	 
078	                        //    if (listView1.Items[i].SubItems[3].ToString() != null)
079	                        //    {
080	                        //        string test = listView1.Items[i].SubItems[3].ToString();
081	                                 
082	                        //        newList.SubItems.Add(test);
083	                        //    }
084	                            
085	                        //}
086	 
087	                        listView1.Items.Remove(items);
088	                         
089	 
090	                    }
091	                    catch (Exception ex)
092	                        {
093	                        MessageBox.Show("Error" + ex);
094	                        }
095	                }
096	                 
097	            }
098	 
099	        }
100	 
101	        
102	        //Add Note Button Click
103	        public void button2_Click(object sender, EventArgs e)
104	        {
105	            mySelectedItems = listView1.SelectedItems;
106	             
107	 
108	            if (textBox1.Text != null && mySelectedItems.Count > 0)
109	             
110	                try
111	                {
112	                    foreach (ListViewItem itemsForNote in mySelectedItems)
113	                        itemsForNote.SubItems.Add(textBox1.Text);
114	                    
115	                }
116	                catch (Exception ex)
117	                {
118	                    MessageBox.Show("Error" + ex);
119	                }
120	 
121	                else
122	                {
123	                    MessageBox.Show("Please select DMs and write note in the box", "Forgotton Something?");
124	                }
125	                 
126	             
127	        }
128	 
129	        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
130	        {
131	             
132	        }
133	 
134	        //Remove Note
135	        private void removeNoteToolStripMenuItem_Click(object sender, EventArgs e)
136	        {
137	             
138	             
139	            try
140	                {
141	                    foreach (ListViewItem myItem in mySelectedItems)
142	                        myItem.SubItems.Remove(myItem.SubItems[3]);
143	                }
144	                catch (Exception ex)
145	                {
146	                    MessageBox.Show("Error" + ex);
147	                }
Posted

1 solution

Might I suggest an alternate approach to what you have posted...

Because you seem to tie the contents of the list views to the contents of a folder, I would suggest that you create a refresh function for each list box. In that function, clear the items collection of the list box and then enumerate the target folder adding the information for each file. This will clear any selections the user may have made previously but it will guarantee that the list box always reflects the contents of the directory after the refresh method has been called. If push came to shove, you could compare the two result sets and update the collection for the list box.

I would then make your move method simply move the target files without regard to the list boxes calling the refresh methods once the moves have completed. This has the added benefit of removing your tallying efforts (simplifying the code) and reflecting the actual status of the files after the move. If a file failed to move for some reason, the user wouldn't be misled because the list boxes would indicate that it had been moved.

The best solution might be to call the refresh methods as soon as you know the directory locations (at app startup) then setup a DirectoryWatcher that notifies you when the contents of the watched directories change. In that handler you could call your refresh method. (Although you might consider inhibiting that functionality while you are doing the file moves.) The advantage with the directory watcher is that your app would reflect file moves... as they happened... inside or outside your application. Of course, you have to be careful here because the directory watcher events may come on a different thread and you would have to marshall the call to the refresh methods over to the UI thread to avoid a cross-thread exception.

As for your notes problem... the issue would seem bigger than just getting the data across the list boxes. For example, how are you persisting this from one session to the next? That is probably the solution to the list box issue as well. You should have some mechanism to match the persisted note information up with the associated file. That mechanism is the same regardless of which list the file would appear in. You would need to persist the notes prior to the move but once the move was complete, and you refreshed the data in the list boxes, you would be able to match the notes back up for each list box.

One solution to persisting the data might be an xml file or a backend database. You could also use NTFS file streams if you can be sure the files will ALWAYS live on NTFS partitions. (If they get moved to a FAT partition, the secondary data fork will be dropped). There is an article on using this feature here.
 
Share this answer
 
Comments
DaedalusAero 23-Jan-13 16:08pm    
Jason, thank you very much for such a detailed explanation. I can't say as i I understood everything you said but I will work through your suggestions and figure it out as I go.

I'm a beginner as you can no doubt tell, and the help and pointers are much appreciated.

Jake
Jason Gleim 24-Jan-13 11:42am    
No worries Jake! Everyone is a beginner at some point and we're all here to help each other get better! I hope your project goes well.

Fortunately, there is a lot of documentation out there on the things I suggested... some of that stuff is just in the 'corners' of the framework that people don't generally come across. I did make a mistake though... I referred to the DirectoryWatcher when in reality it is the FileSystemWatcher class in the System.IO namespace. Since it seems your app is mainly working with files, I would suggest going through that namespace and becoming familiar with the classes in it and what they offer. There is LOTS of really useful stuff in that space.


If you find yourself in a corner, shoot me a PM, I'll see if I can give you some help.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900