www.pudn.com > ObjectListViewDemo.zip > MainForm.cs


/* 
 * ObjectListViewDemo - A simple demo to show the ObjectListView control 
 * 
 * User: Phillip Piper 
 * Date: 15/10/2006 11:15 AM 
 * 
 * Change log: 
 * 2006-10-20  JPP  Added DataSet tab page 
 * 2006-10-15  JPP  Initial version 
 */ 
 
using System; 
using System.IO; 
using System.Data; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Collections; 
using System.Collections.Generic; 
using System.Windows.Forms; 
using System.Diagnostics; 
using System.Threading; 
 
using BrightIdeasSoftware; 
 
namespace ObjectListViewDemo 
{ 
	///  
	/// Description of MainForm. 
	///  
	public partial class MainForm 
	{ 
        ///  
        ///  
        ///  
        ///  
		[STAThread] 
        public static void Main(string[] args) 
		{ 
			Application.EnableVisualStyles(); 
			Application.SetCompatibleTextRenderingDefault(false); 
			Application.Run(new MainForm()); 
		} 
 
        ///  
        ///  
        ///  
		public MainForm() 
		{ 
			// 
			// The InitializeComponent() call is required for Windows Forms designer support. 
			// 
			InitializeComponent(); 
			InitializeExamples(); 
		} 
 
		List masterList; 
		void InitializeExamples()  
		{ 
			masterList = new List(); 
            masterList.Add(new Person("Wilhelm Frat", "Gymnast", 19, new DateTime(1984, 9, 23), 45.67, false, "Aggressive, belligerent ")); 
            masterList.Add(new Person("Alana Roderick", "Gymnast", 21, new DateTime(1974, 9, 23), 245.67, false, "Beautiful, exquisite")); 
            masterList.Add(new Person("Frank Price", "Dancer", 30, new DateTime(1965, 11, 1), 75.5, false, "Competitive, spirited")); 
            masterList.Add(new Person("Eric", "Half-a-bee", 1, new DateTime(1966, 10, 12), 12.25, true, "Diminutive, vertically challenged")); 
            masterList.Add(new Person("Madalene Alright", "School Teacher", 21, new DateTime(1964, 9, 23), 145.67, false, "Extensive, dimensionally challenged")); 
            masterList.Add(new Person("Ned Peirce", "School Teacher", 21, new DateTime(1960, 1, 23), 145.67, false, "Fulsome, effusive")); 
            masterList.Add(new Person("Felicity Brown", "Economist", 30, new DateTime(1975, 1, 12), 175.5, false, "Gifted, exceptional")); 
            masterList.Add(new Person("Urny Unmin", "Economist", 41, new DateTime(1956, 9, 24), 212.25, true, "Heinous, aesthetically challenged")); 
            masterList.Add(new Person("Terrance Darby", "Singer", 35, new DateTime(1970, 9, 29), 1145, false, "Introverted, relationally challenged")); 
            masterList.Add(new Person("Phillip Nottingham", "Programmer", 27, new DateTime(1974, 8, 28), 245.7, false, "Jocular, gregarious")); 
			masterList.Add(new Person("Mister Null")); 
 
 
 
            List list = new List(); 
            foreach (Person p in masterList) 
                list.Add(new Person(p)); 
 
            // Change this value to see the performance on bigger lists. 
            // Each list builds about 1000 rows per second. 
            //while (list.Count < 2000) { 
            //    foreach (Person p in masterList) 
            //        list.Add(new Person(p)); 
            //} 
 
			InitializeSimpleExample(list); 
			InitializeComplexExample(list); 
			InitializeDataSetExample(); 
			InitializeVirtualListExample(); 
			InitializeExplorerExample(); 
            InitializeListPrinting(); 
            InitializeFastListExample(list); 
 
#if MONO 
            // As of 2008-03-23, grid lines on virtual lists crashes the program 
            this.listViewVirtual.GridLines = false; 
            this.olvFastList.GridLines = false; 
#endif 
        } 
 
		void TimedRebuildList (ObjectListView olv) 
		{ 
			Stopwatch stopWatch = new Stopwatch(); 
 
			try { 
				this.Cursor = Cursors.WaitCursor; 
				stopWatch.Start(); 
				olv.BuildList(); 
			} finally { 
				stopWatch.Stop(); 
				this.Cursor = Cursors.Default; 
			} 
 
			this.toolStripStatusLabel1.Text = 
				String.Format("Build time: {0} items in {1}ms, average per item: {2:F}ms", 
				              olv.Items.Count, 
				              stopWatch.ElapsedMilliseconds, 
				              (float)stopWatch.ElapsedMilliseconds / olv.Items.Count); 
		} 
 
		void InitializeSimpleExample(List list) 
		{ 
			// Uncomment these to see the speed difference between reflection and delegates 
			// On my machine, delegates are between 5-10x faster. 
            this.columnHeader11.AspectGetter = delegate(object x) { return ((Person)x).Name; }; 
            this.columnHeader12.AspectGetter = delegate(object x) { return ((Person)x).Occupation; }; 
            this.columnHeader13.AspectGetter = delegate(object x) { return ((Person)x).CulinaryRating; }; 
            this.columnHeader14.AspectGetter = delegate(object x) { return ((Person)x).YearOfBirth; }; 
            this.columnHeader15.AspectGetter = delegate(object x) { return ((Person)x).BirthDate; }; 
            this.columnHeader16.AspectGetter = delegate(object x) { return ((Person)x).GetRate(); }; 
            // Give this column an aspect putter, since it fetches its value using a method rather than a property 
            this.columnHeader16.AspectPutter = delegate(object x, object newValue) { ((Person)x).SetRate((double)newValue); }; 
             
            this.comboBox6.SelectedIndex = 0; 
 
			// Just one line of code make everything happen. 
			this.listViewSimple.SetObjects(list); 
		} 
 
		void InitializeComplexExample(List list) 
		{ 
			this.personColumn.AspectGetter = delegate (object row) { 
				return ((Person)row).Name.ToUpperInvariant(); 
			}; 
			this.personColumn.ImageGetter = delegate (object row) { 
				// People whose names start with a vowel get a star, 
				// otherwise the first half of the alphabet gets hearts 
				// and the second half gets music 
				if ("AEIOU".Contains(((Person)row).Name.Substring(0, 1))) 
					return 0; // star 
				else if (((Person)row).Name.CompareTo("N") < 0) 
					return 1; // heart 
				else 
					return 2; // music 
			}; 
 
            // Cooking skill columns 
            this.columnCookingSkill.AspectGetter = delegate(object row) { 
                return ((Person)row).CulinaryRating; 
            }; 
            this.columnCookingSkill.Renderer = new MultiImageRenderer(Resource1.star16, 5, 0, 40); 
            this.columnCookingSkill.MakeGroupies( 
                new Int32[]{10, 20, 30, 40}, 
                new String[] {"Pay to eat out", "Suggest take-away", "Passable", "Seek dinner invitation", "Hire as chef"}); 
 
            // Hourly rate column 
            this.hourlyRateColumn.MakeGroupies( 
                new Double[] { 100, 1000 },  
                new string[] { "Less than $100", "$100-$1000", "Megabucks" }); 
            this.hourlyRateColumn.AspectPutter = delegate(object x, object newValue) { ((Person)x).SetRate((double)newValue); }; 
 
            // Salary indicator column 
            this.moneyImageColumn.AspectGetter = delegate(object row) { 
                if (((Person)row).GetRate() < 100) return "Little"; 
                if (((Person)row).GetRate() > 1000) return "Lots"; 
                return "Medium"; 
            }; 
            this.moneyImageColumn.Renderer = new MappedImageRenderer(new Object[] { "Little", Resource1.down16, "Medium", Resource1.tick16, "Lots", Resource1.star16 }); 
 
            // Birthday column 
            this.birthdayColumn.GroupKeyGetter = delegate(object row) { 
				return ((Person)row).BirthDate.Month; 
			}; 
			this.birthdayColumn.GroupKeyToTitleConverter = delegate (object key) { 
				return (new DateTime(1, (int)key, 1)).ToString("MMMM"); 
			}; 
			this.birthdayColumn.ImageGetter = delegate (object row) { 
				Person p = (Person)row; 
				if (p.BirthDate != null && (p.BirthDate.Year % 10) == 4) 
					return 3; 
				else 
					return -1; // no image 
			}; 
 
			// Use this column to test sorting and group on TimeSpan objects 
			this.daysSinceBirthColumn.AspectGetter = delegate (object row) { 
				return DateTime.Now - ((Person)row).BirthDate; 
			}; 
			this.daysSinceBirthColumn.AspectToStringConverter = delegate (object aspect) { 
				return ((TimeSpan)aspect).Days.ToString(); 
			}; 
 
            // Uncomment these to get maximum speed 
            this.occupationColumn.AspectGetter = delegate(object row) { 
                return ((Person)row).Occupation; 
            }; 
            this.hourlyRateColumn.AspectGetter = delegate(object row) { 
                return ((Person)row).GetRate(); 
            }; 
            this.hourlyRateColumn.AspectGetter = delegate(object row) { 
                return ((Person)row).GetRate(); 
            }; 
            this.birthdayColumn.AspectGetter = delegate(object row) { 
                return ((Person)row).BirthDate; 
            }; 
 
            comboBox1.SelectedIndex = 4; 
            comboBox5.SelectedIndex = 0; 
            listViewComplex.SetObjects(list); 
		} 
 
		void InitializeDataSetExample () 
		{ 
			this.olvColumn1.ImageGetter  = delegate (object row) { return "user"; }; 
 
            this.salaryColumn.MakeGroupies( 
                new UInt32[] { 20000, 100000 },  
                new string[] { "Lowly worker", "Middle management", "Rarified elevation" }); 
            this.salaryColumn.Renderer = new MultiImageRenderer(Resource1.tick16, 5, 10000, 500000); 
 
            this.heightColumn.MakeGroupies( 
                new Double[] { 1.50, 1.70, 1.85 },  
                new string[] { "Shortie",  "Normal", "Tall", "Really tall" }); 
            this.heightColumn.Renderer = new BarRenderer(0, 2); 
 
            this.olvColumnGif.Renderer = new ImageRenderer(true); 
             
            this.comboBox3.SelectedIndex = 4; 
            this.comboBox7.SelectedIndex = 0; 
 
            this.listViewDataSet.RowFormatter = delegate(OLVListItem olvi) { 
                string[] colorNames = new string[] { "red", "green", "blue", "yellow" }; 
 
                // For some reason, changes to the background of column 0 don't take place 
                // immediately. The list has to be rebuild before the background color changes. 
                foreach (ListViewItem.ListViewSubItem subItem in olvi.SubItems) { 
                    foreach (string name in colorNames) { 
                        if (subItem.Text.ToLowerInvariant().Contains(name)) { 
                            olvi.UseItemStyleForSubItems = false; 
                            if (subItem.Text.ToLowerInvariant().Contains("bk-" + name)) 
                                subItem.BackColor = Color.FromName(name); 
                            else 
                                subItem.ForeColor = Color.FromName(name); 
                        } 
                    } 
                    FontStyle style = FontStyle.Regular; 
                    if (subItem.Text.ToLowerInvariant().Contains("bold"))  
                        style |= FontStyle.Bold; 
                    if (subItem.Text.ToLowerInvariant().Contains("italic"))  
                        style |= FontStyle.Italic; 
                    if (subItem.Text.ToLowerInvariant().Contains("underline"))  
                        style |= FontStyle.Underline; 
                    if (subItem.Text.ToLowerInvariant().Contains("strikeout"))  
                        style |= FontStyle.Strikeout; 
                         
                    if (style != FontStyle.Regular) { 
                        olvi.UseItemStyleForSubItems = false; 
                        subItem.Font = new Font(subItem.Font, style); 
                    } 
                } 
            }; 
 
            this.rowHeightUpDown.Value = 32; 
 
            LoadXmlIntoList(); 
		} 
 
        // A sorter to order Person objects according to a given column in a list view 
        internal class MasterListSorter : Comparer 
        { 
            public MasterListSorter(OLVColumn col, SortOrder order) 
            { 
                this.column = col; 
                this.sortOrder = order; 
            } 
            private OLVColumn column; 
            private SortOrder sortOrder; 
 
            public override int Compare(Person x, Person y) 
            { 
                IComparable xValue = this.column.GetValue(x) as IComparable; 
                IComparable yValue = this.column.GetValue(y) as IComparable; 
 
                int result = 0; 
                if (xValue == null || yValue == null) { 
                    if (xValue == null && yValue == null) 
                        result = 0; 
                    else 
                        if (xValue != null) 
                            result = 1; 
                        else 
                            result = -1; 
                } else  
                    result = xValue.CompareTo(yValue); 
                 
                if (this.sortOrder == SortOrder.Ascending) 
                    return result; 
                else 
                    return 0 - result; 
            } 
        } 
 
		void InitializeVirtualListExample () 
		{ 
			this.listViewVirtual.VirtualListSize = 10000000; 
			this.listViewVirtual.RowGetter = delegate (int i) { 
				Person p = masterList[i % masterList.Count]; 
				p.serialNumber = i; 
				return p; 
			}; 
 
            // Install a custom sorter, just to show how it could be done. We don't 
            // have a backing store that can sort all 10 million items, so we have to be 
            // content with sorting the master list and showing that sorted. It gives the idea. 
            this.listViewVirtual.CustomSorter = delegate(OLVColumn col, SortOrder order) { 
                masterList.Sort(new MasterListSorter(col, order)); 
                this.listViewVirtual.BuildList(); 
            }; 
			 
			// Install aspect getters to optimize performance 
			this.olvColumn4.AspectGetter = delegate (object x) {return ((Person)x).Name;}; 
			this.olvColumn5.AspectGetter = delegate (object x) {return ((Person)x).Occupation;}; 
			this.olvColumn7.AspectGetter = delegate (object x) {return ((Person)x).CulinaryRating;}; 
			this.olvColumn8.AspectGetter = delegate (object x) {return ((Person)x).YearOfBirth;}; 
			this.olvColumn9.AspectGetter = delegate (object x) {return ((Person)x).BirthDate;}; 
			this.olvColumn10.AspectGetter = delegate (object x) {return ((Person)x).GetRate();}; 
            this.olvColumn10.AspectPutter = delegate(object x, object newValue) { ((Person)x).SetRate((double)newValue); }; 
 
            // Install a RowFormatter to setup a tooltip on the item 
            this.listViewVirtual.RowFormatter = delegate(OLVListItem lvi) { 
                lvi.ToolTipText = "This is a long tool tip for '" + lvi.Text + "' that does nothing except waste space."; 
            }; 
				 
			this.olvColumn4.ImageGetter = delegate (object row) { 
				// People whose names start with a vowel get a star, 
				// otherwise the first half of the alphabet gets hearts 
				// and the second half gets music 
				if ("AEIOU".Contains(((Person)row).Name.Substring(0, 1))) 
					return 0; // star 
				else if (((Person)row).Name.CompareTo("N") < 0) 
					return 1; // heart 
				else 
					return 2; // music 
			}; 
			this.olvColumn5.ImageGetter  = delegate (object row) { return "user"; }; // user icon 
            this.olvColumn5.Renderer = new BaseRenderer(); 
			 
            this.olvColumn7.Renderer = new MultiImageRenderer("star", 5, 0, 50); 
 
 
            this.comboBox2.SelectedIndex = 4; 
            this.comboBox8.SelectedIndex = 0; 
		} 
		 
		void InitializeExplorerExample() 
		{ 
            // Draw the system icon next to the name 
#if !MONO 
            SysImageListHelper helper = new SysImageListHelper(this.listViewFiles); 
			this.olvColumnFileName.ImageGetter = delegate(object x) { 
                return helper.GetImageIndex(((FileSystemInfo)x).FullName); 
			}; 
#endif    
            // Show the size of files as GB, MB and KBs. Also, group them by  
            // some meaningless divisions 
            this.olvColumnSize.AspectGetter = delegate(object x) { 
                if (x is DirectoryInfo) 
                    return (long)-1; 
 
                try { 
                    return ((FileInfo)x).Length; 
                } catch (System.IO.FileNotFoundException) { 
                    // Mono 1.2.6 throws this for hidden files 
                    return (long)-2; 
                } 
            }; 
            this.olvColumnSize.AspectToStringConverter = delegate(object x) { 
                if ((long)x == -1) // folder 
                    return ""; 
                else 
                    return this.FormatFileSize((long)x); 
            }; 
            this.olvColumnSize.MakeGroupies(new long[] { 0, 1024 * 1024, 512 * 1024 * 1024 }, 
                new string[] { "Folders", "Small", "Big", "Disk space chewer" }); 
 
            // Group by month-year, rather than date 
            // This code is duplicated for FileCreated and FileModified, so we really should 
            // create named methods rather than using anonymous delegates. 
            this.olvColumnFileCreated.GroupKeyGetter = delegate(object x) { 
                DateTime dt = ((FileSystemInfo)x).CreationTime; 
                return new DateTime(dt.Year, dt.Month, 1); 
            }; 
            this.olvColumnFileCreated.GroupKeyToTitleConverter = delegate(object x) { 
                return ((DateTime)x).ToString("MMMM yyyy"); 
            }; 
 
            // Group by month-year, rather than date 
            this.olvColumnFileModified.GroupKeyGetter = delegate(object x) { 
                DateTime dt = ((FileSystemInfo)x).LastWriteTime; 
                return new DateTime(dt.Year, dt.Month, 1); 
            }; 
            this.olvColumnFileModified.GroupKeyToTitleConverter = delegate(object x) { 
                return ((DateTime)x).ToString("MMMM yyyy"); 
            }; 
 
            // Show the system description for this object 
            this.olvColumnFileType.AspectGetter = delegate(object x) { 
                return ShellUtilities.GetFileType(((FileSystemInfo)x).FullName); 
            }; 
 
            // Show the file attributes for this object 
            this.olvColumnAttributes.AspectGetter = delegate(object x) { 
                return ((FileSystemInfo)x).Attributes; 
            }; 
            FlagRenderer attributesRenderer = new FlagRenderer(); 
            attributesRenderer.Add(FileAttributes.Archive, "archive"); 
            attributesRenderer.Add(FileAttributes.ReadOnly, "readonly"); 
            attributesRenderer.Add(FileAttributes.System, "system"); 
            attributesRenderer.Add(FileAttributes.Hidden, "hidden"); 
            attributesRenderer.Add(FileAttributes.Temporary, "temporary"); 
            this.olvColumnAttributes.Renderer = attributesRenderer; 
 
            this.comboBox4.SelectedIndex = 4; 
            this.textBoxFolderPath.Text = @"c:\"; 
            this.PopulateListFromPath(this.textBoxFolderPath.Text); 
		} 
 
        void InitializeListPrinting() 
        { 
            // For some reason the Form Designer loses these settings 
            this.printPreviewControl1.Zoom = 1; 
            this.printPreviewControl1.AutoZoom = true; 
 
            this.UpdatePrintPreview(); 
        } 
 
        string FormatFileSize(long size) 
        { 
            int[] limits = new int[] { 1024 * 1024 * 1024, 1024 * 1024, 1024 }; 
            string[] units = new string[] { "GB", "MB", "KB" }; 
 
            for (int i = 0; i < limits.Length; i++) { 
                if (size >= limits[i]) 
                    return String.Format("{0:#,##0.##} " + units[i], ((double)size / limits[i])); 
            } 
 
            return String.Format("{0} bytes", size); ; 
        } 
 
		void LoadXmlIntoList() 
		{ 
			DataSet ds = LoadDatasetFromXml("Persons.xml"); 
 
			if (ds.Tables.Count > 0) 
			{ 
#if !MONO 
				this.dataGridView1.DataSource = ds; 
				this.dataGridView1.DataMember = "Person"; 
#endif								 
				// Test with BindingSource 
#if !MONO 
                this.listViewDataSet.DataSource = new BindingSource(ds, "Person"); 
#endif 
 
                // Test with DataTable 
#if MONO 
                DataTable personTable = ds.Tables["Person"]; 
                this.listViewDataSet.DataSource = personTable; 
#endif 
 
                // Test with DataView 
                //this.listViewDataSet.DataSource = new DataView(personTable); 
 
                // Test with DataSet 
                //this.listViewDataSet.DataMember = "Person"; 
                //this.listViewDataSet.DataSource = ds; 
 
                // Test with DataViewManager 
                //this.listViewDataSet.DataMember = "Person"; 
                //this.listViewDataSet.DataSource = new DataViewManager(ds); 
 
				// Test with nulls 
                //this.listViewDataSet.DataMember = null; 
                //this.listViewDataSet.DataSource = null; 
			} 
		} 
 
		DataSet LoadDatasetFromXml(string fileName) 
		{ 
			DataSet ds = new DataSet(); 
			FileStream fs = null; 
 
			try { 
				fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); 
				StreamReader reader = new StreamReader(fs); 
	      		ds.ReadXml(reader); 
			} catch (Exception e) { 
				MessageBox.Show(e.ToString()); 
			} finally { 
				if (fs != null) 
					fs.Close(); 
			} 
 
			return ds; 
		} 
 
		void TimedReloadXml () 
		{ 
			Stopwatch stopWatch = new Stopwatch(); 
 
			try { 
				this.Cursor = Cursors.WaitCursor; 
				stopWatch.Start(); 
				this.LoadXmlIntoList(); 
			} finally { 
				stopWatch.Stop(); 
				this.Cursor = Cursors.Default; 
			} 
 
			this.toolStripStatusLabel1.Text = 
				String.Format("XML Load: {0} items in {1}ms, average per item: {2:F}ms", 
				              listViewDataSet.Items.Count, 
				              stopWatch.ElapsedMilliseconds, 
				              stopWatch.ElapsedMilliseconds / listViewDataSet.Items.Count); 
        } 
 
        #region Form event handlers 
 
        private void MainForm_Load(object sender, EventArgs e) 
        { 
        } 
         
        #endregion 
 
        #region Utilities 
 
        void ShowGroupsChecked(ObjectListView olv, CheckBox cb) 
		{ 
			olv.ShowGroups = cb.Checked; 
			olv.BuildList(); 
		} 
 
		void ShowLabelsOnGroupsChecked(ObjectListView olv, CheckBox cb) 
		{ 
			olv.ShowItemCountOnGroups = cb.Checked; 
			olv.BuildGroups(); 
        } 
 
        void HandleSelectionChanged(ObjectListView listView) 
        { 
            string msg; 
            Person p = (Person)listView.GetSelectedObject(); 
            if (p == null) 
                msg = listView.SelectedIndices.Count.ToString(); 
            else 
                msg = "'" + p.Name + "'"; 
            this.toolStripStatusLabel1.Text = String.Format("Selected {0} of {1} items", msg, listView.GetItemCount()); 
        } 
 
        void ListViewSelectedIndexChanged(object sender, System.EventArgs e) 
        { 
            HandleSelectionChanged((ObjectListView)sender); 
        } 
 
        private void ChangeView(ObjectListView listview, ComboBox comboBox) 
        { 
            if (listview.VirtualMode && comboBox.SelectedIndex == 3) 
                MessageBox.Show("Sorry, Microsoft says that virtual lists can't use Tile view.", "Object List View Demo", MessageBoxButtons.OK, MessageBoxIcon.Information); 
            else 
                switch (comboBox.SelectedIndex) { 
                    case 0: listview.View = View.SmallIcon; break; 
                    case 1: listview.View = View.LargeIcon; break; 
                    case 2: listview.View = View.List; break; 
                    case 3: listview.View = View.Tile; break; 
                    case 4: listview.View = View.Details; break; 
                } 
        } 
 
        void ChangeOwnerDrawn(ObjectListView listview, CheckBox cb) 
        { 
            listview.OwnerDraw = cb.Checked; 
            listview.BuildList(); 
        } 
		 
        #endregion 
 
        #region Simple Tab Event Handlers 
 
		void CheckBox3CheckedChanged(object sender, System.EventArgs e) 
		{ 
			ShowGroupsChecked(this.listViewSimple, (CheckBox)sender); 
		} 
 
		void CheckBox4CheckedChanged(object sender, System.EventArgs e) 
		{ 
			ShowLabelsOnGroupsChecked(this.listViewSimple, (CheckBox)sender); 
		} 
 
		void Button1Click(object sender, System.EventArgs e) 
		{ 
            this.TimedRebuildList(this.listViewSimple); 
		} 
 
		void Button4Click(object sender, System.EventArgs e) 
		{ 
			// Silly example just to make sure that object selection works 
 
			listViewSimple.SelectedObjects = listViewComplex.SelectedObjects; 
			listViewSimple.Select(); 
		} 
 
        private void button7_Click(object sender, EventArgs e) 
        { 
            this.listViewSimple.SelectedItem = this.listViewSimple.GetNextItem(this.listViewSimple.SelectedItem); 
        } 
 
        private void button6_Click(object sender, EventArgs e) 
        { 
            this.listViewSimple.SelectedItem = this.listViewSimple.GetPreviousItem(this.listViewSimple.SelectedItem); 
        } 
 
        #endregion 
 
        #region Complex Tab Event Handlers 
 
        void CheckBox1CheckedChanged(object sender, System.EventArgs e) 
		{ 
			ShowGroupsChecked(this.listViewComplex, (CheckBox)sender); 
		} 
 
		void CheckBox2CheckedChanged(object sender, System.EventArgs e) 
		{ 
			ShowLabelsOnGroupsChecked(this.listViewComplex, (CheckBox)sender); 
		}         
 
		void Button2Click(object sender, System.EventArgs e) 
		{ 
            this.TimedRebuildList(this.listViewComplex); 
        } 
 
		void Button5Click(object sender, System.EventArgs e) 
		{ 
            listViewComplex.SelectedObjects = listViewSimple.SelectedObjects; 
            listViewComplex.Select(); 
		} 
        		 
		void CheckBox6CheckedChanged(object sender, EventArgs e) 
		{ 
            ChangeOwnerDrawn(this.listViewComplex, (CheckBox)sender); 
		} 
 
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            this.ChangeView(this.listViewComplex, (ComboBox)sender); 
        } 
        #endregion 
 
        #region Dataset Tab Event Handlers 
 
		void CheckBox7CheckedChanged(object sender, System.EventArgs e) 
		{ 
			ShowGroupsChecked(this.listViewDataSet, (CheckBox)sender); 
		} 
 
		void CheckBox8CheckedChanged(object sender, System.EventArgs e) 
		{ 
			ShowLabelsOnGroupsChecked(this.listViewDataSet, (CheckBox)sender); 
		} 
 
		void Button3Click(object sender, System.EventArgs e) 
		{ 
			this.TimedReloadXml(); 
        } 
 
        void CheckBox5CheckedChanged(object sender, EventArgs e) 
        { 
            ChangeOwnerDrawn(this.listViewDataSet, (CheckBox)sender); 
        } 
 
        private void comboBox3_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            this.ChangeView(this.listViewDataSet, (ComboBox)sender); 
        } 
 
        void ListViewDataSetSelectedIndexChanged(object sender, System.EventArgs e) 
        { 
            ObjectListView listView = (ObjectListView)sender; 
            DataRowView row = (DataRowView)listView.GetSelectedObject(); 
            string msg; 
            if (row == null) 
                msg = listView.SelectedIndices.Count.ToString(); 
            else 
                msg = "'" + row["Name"] + "'"; 
            this.toolStripStatusLabel1.Text = String.Format("Selected {0} of {1} items", msg, listView.Items.Count); 
 
        } 
 
        private void rowHeightUpDown_ValueChanged(object sender, EventArgs e) 
        { 
            this.listViewDataSet.RowHeight = Decimal.ToInt32(this.rowHeightUpDown.Value); 
        } 
 
        private void checkBoxPause_CheckedChanged(object sender, EventArgs e) 
        { 
            this.listViewDataSet.PauseAnimations(((CheckBox)sender).Checked); 
        } 
 
        #endregion 
 
        #region Virtual Tab Event Handlers 
		 
		void CheckBox9CheckedChanged(object sender, EventArgs e) 
		{ 
            this.ChangeOwnerDrawn(this.listViewVirtual, (CheckBox)sender); 
        } 
 
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            this.ChangeView(this.listViewVirtual, (ComboBox)sender); 
        } 
 
        private void button8_Click(object sender, EventArgs e) 
        { 
            this.listViewVirtual.SelectAll(); 
        } 
 
        private void button9_Click(object sender, EventArgs e) 
        { 
            this.listViewVirtual.DeselectAll(); 
        } 
 
		#endregion 
 
        #region Explorer Tab event handlers 
 
        void TextBoxFolderPathTextChanged(object sender, EventArgs e) 
		{ 
            if (Directory.Exists(this.textBoxFolderPath.Text)) { 
                this.textBoxFolderPath.ForeColor = Color.Black; 
                this.buttonGo.Enabled = true; 
                this.buttonUp.Enabled = true; 
            } else { 
                this.textBoxFolderPath.ForeColor = Color.Red; 
                this.buttonGo.Enabled = false; 
                this.buttonUp.Enabled = false; 
            } 
        } 
		 
		void ButtonGoClick(object sender, EventArgs e) 
		{ 
			string path = this.textBoxFolderPath.Text; 
			this.PopulateListFromPath(path); 
		} 
		 
		void PopulateListFromPath(string path) 
		{ 
			DirectoryInfo pathInfo = new DirectoryInfo(path); 
			if (!pathInfo.Exists) 
				return; 
 
            Stopwatch sw = new Stopwatch(); 
 
            Cursor.Current = Cursors.WaitCursor; 
            sw.Start(); 
			this.listViewFiles.SetObjects(pathInfo.GetFileSystemInfos()); 
            sw.Stop(); 
            Cursor.Current = Cursors.Default; 
 
            float msPerItem = (listViewFiles.Items.Count == 0 ? 0 : (float)sw.ElapsedMilliseconds / listViewFiles.Items.Count); 
            this.toolStripStatusLabel1.Text = String.Format("Timed build: {0} items in {1}ms ({2:F}ms per item)", 
                listViewFiles.Items.Count, sw.ElapsedMilliseconds, msPerItem); 
		} 
		 
		void CheckBox12CheckedChanged(object sender, EventArgs e) 
		{ 
			ShowGroupsChecked(this.listViewFiles, (CheckBox)sender);			 
		} 
		 
		void CheckBox11CheckedChanged(object sender, EventArgs e) 
		{ 
            this.ShowLabelsOnGroupsChecked(this.listViewFiles, (CheckBox)sender); 
		} 
		 
		void CheckBox10CheckedChanged(object sender, EventArgs e) 
		{ 
            this.ChangeOwnerDrawn(this.listViewFiles, (CheckBox)sender); 
		} 
		 
		void ComboBox4SelectedIndexChanged(object sender, EventArgs e) 
		{ 
           this.ChangeView(this.listViewFiles, (ComboBox)sender); 
           this.button13.Enabled = (this.listViewFiles.View == View.Details || this.listViewFiles.View == View.Tile); 
       } 
 
        private void listViewFiles_ItemActivate(object sender, EventArgs e) 
        { 
            Object rowObject = this.listViewFiles.SelectedObject; 
            if (rowObject == null) 
                return; 
 
            if (rowObject is DirectoryInfo) { 
                this.textBoxFolderPath.Text = ((DirectoryInfo)rowObject).FullName; 
                this.buttonGo.PerformClick(); 
            } else { 
                ShellUtilities.Execute(((FileInfo)rowObject).FullName); 
            } 
        } 
 
        private void textBoxFolderPath_KeyPress(object sender, KeyPressEventArgs e) 
        { 
            if (e.KeyChar == (char)13) { 
                this.buttonGo.PerformClick(); 
                e.Handled = true; 
            } 
        } 
 
        private void buttonUp_Click(object sender, EventArgs e) 
        { 
            DirectoryInfo di = Directory.GetParent(this.textBoxFolderPath.Text); 
            if (di == null) 
                System.Media.SystemSounds.Asterisk.Play(); 
            else { 
                this.textBoxFolderPath.Text = di.FullName; 
                this.buttonGo.PerformClick(); 
            } 
        } 
        #endregion 
 
        #region Testing Only 
 
        void RunTimingTest() 
        { 
            Stopwatch sw = new Stopwatch(); 
 
            Person p = this.masterList[0]; 
            OLVColumn colIndirect = new OLVColumn("name", "Name"); 
            OLVColumn colDirect = new OLVColumn(); 
            colDirect.AspectGetter = delegate(object x) { return ((Person)x).Name; }; 
 
            string name; 
            int iterations = 1000000; 
 
            sw.Start(); 
            for (int i = 0; i < iterations; i++) 
                name = (string)colDirect.GetValue(p); 
            sw.Stop(); 
            long durationDirect = sw.ElapsedMilliseconds; 
 
            sw.Reset(); 
            sw.Start(); 
            for (int i = 0; i < iterations; i++) 
                name = (string)colIndirect.GetValue(p); 
            sw.Stop(); 
            long durationIndirect = sw.ElapsedMilliseconds; 
 
            MessageBox.Show(String.Format("direct duration: {0}\nindirect duration: {1}", durationDirect, durationIndirect)); 
        } 
 
        #endregion 
 
        #region ListView printing 
 
        private void button10_Click_1(object sender, EventArgs e) 
        { 
            this.listViewPrinter1.PageSetup(); 
            this.UpdatePrintPreview(); 
        } 
 
        private void button11_Click(object sender, EventArgs e) 
        { 
            this.listViewPrinter1.PrintPreview(); 
        } 
 
        private void button12_Click(object sender, EventArgs e) 
        { 
            if (rbShowVirtual.Checked == true) { 
                string msg = "Be careful when printing the virtual list.\n\nIt contains 10 million rows. If you select to print all pages, it will try to print 250,000 pages! That seems little excessive for a demo.\n\nYou have been warned."; 
                MessageBox.Show(msg, "Be careful", MessageBoxButtons.OK, MessageBoxIcon.Warning); 
            } 
            this.listViewPrinter1.PrintWithDialog(); 
        } 
 
        void Button13Click(object sender, EventArgs e) 
        { 
            this.UpdatePrintPreview(); 
        } 
 
        void UpdatePreview(object sender, EventArgs e) 
        { 
            this.UpdatePrintPreview(); 
        } 
 
        void UpdatePrintPreview() 
        { 
            if (this.rbShowSimple.Checked == true) 
				this.listViewPrinter1.ListView = this.listViewSimple; 
			else if (this.rbShowComplex.Checked == true) 
				this.listViewPrinter1.ListView = this.listViewComplex; 
			else if (this.rbShowDataset.Checked == true) 
				this.listViewPrinter1.ListView = this.listViewDataSet; 
            else if (this.rbShowVirtual.Checked == true) 
                this.listViewPrinter1.ListView = this.listViewVirtual; 
            else if (this.rbShowFileExplorer.Checked == true) 
                this.listViewPrinter1.ListView = this.listViewFiles; 
			 
			this.listViewPrinter1.DocumentName = this.tbTitle.Text; 
			this.listViewPrinter1.Header = this.tbHeader.Text.Replace("\\t", "\t"); 
            this.listViewPrinter1.Footer = this.tbFooter.Text.Replace("\\t", "\t"); 
			this.listViewPrinter1.Watermark = this.tbWatermark.Text; 
			 
			this.listViewPrinter1.IsShrinkToFit = this.cbShrinkToFit.Checked; 
			this.listViewPrinter1.IsTextOnly = !this.cbIncludeImages.Checked; 
			this.listViewPrinter1.IsPrintSelectionOnly = this.cbPrintOnlySelection.Checked; 
			 
			if (this.rbStyleMinimal.Checked == true) 
				this.ApplyMinimalFormatting(); 
			else if (this.rbStyleModern.Checked == true) 
				this.ApplyModernFormatting(); 
			else if (this.rbStyleTooMuch.Checked == true) 
				this.ApplyOverTheTopFormatting(); 
 
            if (this.cbCellGridLines.Checked == false) 
                this.listViewPrinter1.ListGridPen = null; 
 
            this.listViewPrinter1.FirstPage = (int)this.numericUpDown1.Value; 
            this.listViewPrinter1.LastPage = (int)this.numericUpDown2.Value; 
 
            this.printPreviewControl1.InvalidatePreview(); 
		} 
 
        ///  
        /// Give the report a minimal set of default formatting values. 
        ///  
        public void ApplyMinimalFormatting() 
        { 
            this.listViewPrinter1.CellFormat = null; 
            this.listViewPrinter1.ListFont = new Font("Tahoma", 9); 
 
            this.listViewPrinter1.HeaderFormat = BlockFormat.Header(); 
            this.listViewPrinter1.HeaderFormat.TextBrush = Brushes.Black; 
            this.listViewPrinter1.HeaderFormat.BackgroundBrush = null; 
            this.listViewPrinter1.HeaderFormat.SetBorderPen(Sides.Bottom, new Pen(Color.Black, 0.5f)); 
 
            this.listViewPrinter1.FooterFormat = BlockFormat.Footer(); 
            this.listViewPrinter1.GroupHeaderFormat = BlockFormat.GroupHeader(); 
            Brush brush = new LinearGradientBrush(new Point(0, 0), new Point(200, 0), Color.Gray, Color.White); 
            this.listViewPrinter1.GroupHeaderFormat.SetBorder(Sides.Bottom, 2, brush); 
 
            this.listViewPrinter1.ListHeaderFormat = BlockFormat.ListHeader(); 
            this.listViewPrinter1.ListHeaderFormat.BackgroundBrush = null; 
 
            this.listViewPrinter1.WatermarkFont = null; 
            this.listViewPrinter1.WatermarkColor = Color.Empty; 
        } 
 
        ///  
        /// Give the report a minimal set of default formatting values. 
        ///  
        public void ApplyModernFormatting() 
        { 
            this.listViewPrinter1.CellFormat = null; 
            this.listViewPrinter1.ListFont = new Font("Ms Sans Serif", 9); 
            this.listViewPrinter1.ListGridPen = new Pen(Color.DarkGray, 0.5f); 
 
            this.listViewPrinter1.HeaderFormat = BlockFormat.Header(new Font("Verdana", 24, FontStyle.Bold)); 
            this.listViewPrinter1.HeaderFormat.BackgroundBrush = new LinearGradientBrush(new Point(0, 0), new Point(200, 0), Color.DarkBlue, Color.White); 
 
            this.listViewPrinter1.FooterFormat = BlockFormat.Footer(); 
            this.listViewPrinter1.FooterFormat.BackgroundBrush = new LinearGradientBrush(new Point(0, 0), new Point(200, 0), Color.White, Color.Blue); 
 
            this.listViewPrinter1.GroupHeaderFormat = BlockFormat.GroupHeader(); 
            this.listViewPrinter1.ListHeaderFormat = BlockFormat.ListHeader(new Font("Verdana", 12)); 
 
            this.listViewPrinter1.WatermarkFont = null; 
            this.listViewPrinter1.WatermarkColor = Color.Empty; 
        } 
 
        ///  
        /// Give the report a minimal set of default formatting values. 
        ///  
        public void ApplyOverTheTopFormatting() 
        { 
            this.listViewPrinter1.CellFormat = null; 
            this.listViewPrinter1.ListFont = new Font("Ms Sans Serif", 9); 
            this.listViewPrinter1.ListGridPen = new Pen(Color.Blue, 0.5f); 
 
            this.listViewPrinter1.HeaderFormat = BlockFormat.Header(new Font("Comic Sans MS", 36)); 
            this.listViewPrinter1.HeaderFormat.TextBrush = new LinearGradientBrush(new Point(0, 0), new Point(900, 0), Color.Black, Color.Blue); 
            this.listViewPrinter1.HeaderFormat.BackgroundBrush = new TextureBrush(Resource1.star16, WrapMode.Tile); 
            this.listViewPrinter1.HeaderFormat.SetBorder(Sides.All, 10, new LinearGradientBrush(new Point(0, 0), new Point(300, 0), Color.Purple, Color.Pink)); 
 
            this.listViewPrinter1.FooterFormat = BlockFormat.Footer(new Font("Comic Sans MS", 12)); 
            this.listViewPrinter1.FooterFormat.TextBrush = Brushes.Blue; 
            this.listViewPrinter1.FooterFormat.BackgroundBrush = new LinearGradientBrush(new Point(0, 0), new Point(200, 0), Color.Gold, Color.Green); 
            this.listViewPrinter1.FooterFormat.SetBorderPen(Sides.All, new Pen(Color.FromArgb(128, Color.Green), 5)); 
             
            this.listViewPrinter1.GroupHeaderFormat = BlockFormat.GroupHeader(); 
            Brush brush = new HatchBrush(HatchStyle.LargeConfetti, Color.Blue, Color.Empty); 
            this.listViewPrinter1.GroupHeaderFormat.SetBorder(Sides.Bottom, 5, brush); 
 
            this.listViewPrinter1.ListHeaderFormat = BlockFormat.ListHeader(new Font("Comic Sans MS", 12)); 
            this.listViewPrinter1.ListHeaderFormat.BackgroundBrush = Brushes.PowderBlue; 
            this.listViewPrinter1.ListHeaderFormat.TextBrush = Brushes.Black; 
 
            this.listViewPrinter1.WatermarkFont = new Font("Comic Sans MS", 72); 
            this.listViewPrinter1.WatermarkColor = Color.Red; 
        } 
 
        private void listViewPrinter1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) 
        { 
            this.toolStripStatusLabel1.Text = String.Format("Printing page #{0}...", this.listViewPrinter1.PageNumber); 
            this.Update(); 
        } 
 
        private void listViewPrinter1_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e) 
        { 
            this.toolStripStatusLabel1.Text = "Printing done"; 
        } 
 
        private void tabControl1_Selected(object sender, TabControlEventArgs e) 
        { 
            if (e.TabPageIndex == 5) 
                this.UpdatePrintPreview(); 
        } 
 
        #endregion 
 
        #region Cell editing example 
 
        private void listViewComplex_CellEditStarting(object sender, ObjectListView.CellEditEventArgs e) 
        { 
            // We only want to mess with the Cooking Skill column 
            if (e.Column.Text != "Cooking skill") 
                return; 
 
            ComboBox cb = new ComboBox(); 
            cb.Bounds = e.CellBounds; 
            cb.Font = ((ObjectListView)sender).Font; 
            cb.DropDownStyle = ComboBoxStyle.DropDownList; 
            cb.Items.AddRange(new String[] { "Pay to eat out", "Suggest take-away", "Passable", "Seek dinner invitation", "Hire as chef" }); 
            cb.SelectedIndex = ((int)e.Value) / 10; 
            cb.SelectedIndexChanged += new EventHandler(cb_SelectedIndexChanged); 
            cb.Tag = e.RowObject; // remember which person we are editing 
            e.Control = cb; 
        } 
 
        private void cb_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            ComboBox cb = (ComboBox)sender; 
            ((Person)cb.Tag).CulinaryRating = cb.SelectedIndex * 10; 
        } 
 
        private void listViewComplex_CellEditFinishing(object sender, ObjectListView.CellEditEventArgs e) 
        { 
            // We only want to mess with the Cooking Skill column 
            if (e.Column.Text != "Cooking skill") 
                return; 
 
            // Stop listening for change events 
            ((ComboBox)e.Control).SelectedIndexChanged -= new EventHandler(cb_SelectedIndexChanged); 
 
            // Any updating will have been down in the SelectedIndexChanged event handler 
            // Here we simply make the list redraw the involved ListViewItem 
            ((ObjectListView)sender).RefreshItem(e.ListViewItem); 
 
            // We have updated the model object, so we cancel the auto update 
            e.Cancel = true; 
        } 
 
        private void comboBox5_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            this.ChangeEditable(this.listViewComplex, (ComboBox)sender); 
        } 
 
        private void comboBox6_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            this.ChangeEditable(this.listViewSimple, (ComboBox)sender); 
        } 
 
        private void comboBox7_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            this.ChangeEditable(this.listViewDataSet, (ComboBox)sender); 
        } 
 
        private void comboBox8_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            this.ChangeEditable(this.listViewVirtual, (ComboBox)sender); 
        } 
 
        private void ChangeEditable(ObjectListView objectListView, ComboBox comboBox) 
        { 
            if (comboBox.Text == "No") 
                objectListView.CellEditActivation = ObjectListView.CellEditActivateMode.None; 
            else if (comboBox.Text == "Single Click") 
                objectListView.CellEditActivation = ObjectListView.CellEditActivateMode.SingleClick; 
            else if (comboBox.Text == "Double Click") 
                objectListView.CellEditActivation = ObjectListView.CellEditActivateMode.DoubleClick; 
            else 
                objectListView.CellEditActivation = ObjectListView.CellEditActivateMode.F2Only; 
        } 
 
        #endregion 
 
        private void InitializeFastListExample(List list) 
        { 
            this.olvColumn18.AspectGetter = delegate(object x) { return ((Person)x).Name; }; 
 
            this.olvColumn18.ImageGetter = delegate(object row) { 
                // People whose names start with a vowel get a star, 
                // otherwise the first half of the alphabet gets hearts 
                // and the second half gets music 
                if ("AEIOU".Contains(((Person)row).Name.Substring(0, 1))) 
                    return 0; // star 
                else if (((Person)row).Name.CompareTo("N") < 0) 
                    return 1; // heart 
                else 
                    return 2; // music 
            }; 
 
            this.olvColumn19.AspectGetter = delegate(object x) { return ((Person)x).Occupation; }; 
            this.olvColumn26.AspectGetter = delegate(object x) { return ((Person)x).CulinaryRating; }; 
            this.olvColumn26.Renderer = new MultiImageRenderer(Resource1.star16, 5, 0, 40); 
 
            this.olvColumn27.AspectGetter = delegate(object x) { return ((Person)x).YearOfBirth; }; 
 
            this.olvColumn28.AspectGetter = delegate(object x) { return ((Person)x).BirthDate; }; 
            this.olvColumn28.ImageGetter = delegate(object row) { 
                Person p = (Person)row; 
                if (p.BirthDate != null && (p.BirthDate.Year % 10) == 4) 
                    return 3; 
                else 
                    return -1; // no image 
            }; 
            this.olvColumn28.Renderer = new BaseRenderer(); 
 
            this.olvColumn29.AspectGetter = delegate(object x) { return ((Person)x).GetRate(); }; 
            this.olvColumn29.AspectPutter = delegate(object x, object newValue) { ((Person)x).SetRate((double)newValue); }; 
 
            this.olvColumn31.AspectGetter = delegate(object row) { 
                if (((Person)row).GetRate() < 100) return "Little"; 
                if (((Person)row).GetRate() > 1000) return "Lots"; 
                return "Medium"; 
            }; 
            this.olvColumn31.Renderer = new MappedImageRenderer(new Object[] { "Little", Resource1.down16, "Medium", Resource1.tick16, "Lots", Resource1.star16 }); 
            this.olvColumn32.AspectGetter = delegate(object row) { 
                return DateTime.Now - ((Person)row).BirthDate; 
            }; 
            this.olvColumn32.AspectToStringConverter = delegate(object aspect) { 
                return ((TimeSpan)aspect).Days.ToString(); 
            }; 
            this.olvColumn33.AspectGetter = delegate(object row) { 
                return ((Person)row).CanTellJokes; 
            }; 
 
            comboBox9.SelectedIndex = 0; 
            comboBox10.SelectedIndex = 4; 
 
            this.olvFastList.SetObjects(list); 
        } 
 
        private void button14_Click(object sender, EventArgs e) 
        { 
            int targetNumber = this.olvFastList.GetItemCount() + 1000; 
            ArrayList l = this.olvFastList.Objects; 
            while (l.Count < targetNumber) 
                foreach (Person x in this.masterList) 
                    l.Add(new Person(x)); 
 
            Stopwatch stopWatch = new Stopwatch(); 
            try { 
                this.Cursor = Cursors.WaitCursor; 
                stopWatch.Start(); 
                this.olvFastList.Objects = l; 
            } finally { 
                stopWatch.Stop(); 
                this.Cursor = Cursors.Default; 
            } 
 
            this.takeNoticeOfSelectionEvent = false; 
            this.toolStripStatusLabel1.Text = 
                String.Format("Build time: {0} items in {1}ms, average per item: {2:F}ms", 
                              this.olvFastList.Items.Count, 
                              stopWatch.ElapsedMilliseconds, 
                              (float)stopWatch.ElapsedMilliseconds / this.olvFastList.Items.Count); 
        } 
        private bool takeNoticeOfSelectionEvent = true; 
 
        private void checkBox13_CheckedChanged(object sender, EventArgs e) 
        { 
            ChangeOwnerDrawn(this.olvFastList, (CheckBox)sender); 
        } 
 
        private void comboBox9_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            ChangeEditable(this.olvFastList, (ComboBox)sender); 
        } 
 
        private void comboBox10_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            ChangeView(this.olvFastList, (ComboBox)sender); 
        } 
 
        private void button15_Click(object sender, EventArgs e) 
        { 
            this.olvFastList.SetObjects(null); 
            this.HandleSelectionChanged(this.olvFastList); 
        } 
 
        private void button13_Click(object sender, EventArgs e) 
        { 
            ColumnSelectionForm form = new ColumnSelectionForm(); 
            form.OpenOn(this.listViewFiles); 
        } 
 
        private void olvFastList_SelectionChanged(object sender, EventArgs e) 
        { 
            if (this.takeNoticeOfSelectionEvent) 
                this.HandleSelectionChanged((ObjectListView)sender); 
          
            this.takeNoticeOfSelectionEvent = true; 
        } 
 
        private void listViewVirtual_SelectionChanged(object sender, EventArgs e) 
        { 
            this.HandleSelectionChanged((ObjectListView)sender); 
        } 
    } 
 
	class Person 
	{ 
		public Person(string name) 
		{ 
			this.name = name; 
		} 
 
		public Person(string name, string occupation, int culinaryRating, DateTime birthDate, double hourlyRate, bool canTellJokes, string comments) 
		{ 
			this.name = name; 
			this.Occupation = occupation; 
			this.culinaryRating = culinaryRating; 
			this.birthDate = birthDate; 
			this.hourlyRate = hourlyRate; 
            this.CanTellJokes = canTellJokes; 
            this.Comments = comments; 
		} 
 
        public Person(Person other) 
        { 
            this.name = other.Name; 
            this.Occupation = other.Occupation; 
            this.culinaryRating = other.CulinaryRating; 
            this.birthDate = other.BirthDate; 
            this.hourlyRate = other.GetRate(); 
            this.CanTellJokes = other.CanTellJokes; 
            this.Comments = other.Comments; 
        } 
 
        public string Name 
        { 
            get { return name; } 
            set { name = value; } 
        } 
        private string name; 
 
        // Allows tests for fields. 
        public string Occupation 
        { 
            get { return occupation; } 
            set { occupation = value; } 
        } 
        private string occupation; 
 
		public int CulinaryRating { 
			get { return culinaryRating; } 
            set { culinaryRating = value; } 
        } 
        private int culinaryRating; 
 
		public DateTime BirthDate { 
			get { return birthDate; } 
            set { birthDate = value; } 
        } 
        private DateTime birthDate; 
 
        public int YearOfBirth 
        { 
            get { return this.BirthDate.Year; } 
            set { this.BirthDate = new DateTime(value, birthDate.Month, birthDate.Day); } 
        } 
 
        public double GetRate() 
        { 
            return hourlyRate; 
        } 
        private double hourlyRate; 
 
        public void SetRate(double value) 
        { 
            hourlyRate = value; 
        } 
 
		// Allows tests for fields. 
        public string Comments; 
		public int serialNumber; 
        public bool CanTellJokes; 
	} 
 
}