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;
}
}