using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Diagnostics; using System.Reflection; using System.Collections; using Softelvdm.SftTreeNET; using Softelvdm.Controls; namespace WindowsApplication1 { public partial class PartsSample3 : Form { public PartsSample3() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // This sample demonstrates how sorting indicators could be used in column headers. // To prepare for this sample, create a new project with a blank form and add // a SftTree/NET control named sftTree1. // In addition, adjust the following FromFile method to use a (small) bitmap // that is located on your system. Image img = Bitmap.FromFile("..\\..\\test.gif"); // Most of this initialization code could be eliminated by designing the control. sftTree1.Initializing = true; sftTree1.Columns.Count = 4; for (int c = 0 ; c < sftTree1.Columns.Count ; ++c) { CellClass cell = sftTree1.Headers[0, c]; // access each header cell cell.Text = "Column " + c.ToString(); // set the title if (c == 1) cell.Image = img; // add an image to a random column header cell.SortIndicatorPosition = SortIndicatorPositionEnum.Default; } sftTree1.ItemClick += new SftTree.ItemClickEventHandler(sftTree1_ItemClick); sftTree1.ItemDoubleClick += new SftTree.ItemDoubleClickEventHandler(sftTree1_ItemDoubleClick); // Add a few items ItemClass item = sftTree1.ItemCollection.Add(new string [] { "Text 1", "Data 4", "44", "31" } ); item.Cells[2].TagObject = (long) 44; // we use the actual number for sorting, not the string item.Cells[3].TagObject = (long) 31; item = sftTree1.ItemCollection.Add(new string[] { "Text 2", "Data 2", "22", "28" }); item.Cells[2].TagObject = (long) 22; // we use the actual number for sorting, not the string item.Cells[3].TagObject = (long) 28; item.Cells[3].Image = img; // add an image to a random cell item = sftTree1.ItemCollection.Add(new string[] { "Text 3", "Data 43", "11", "233" }); item.Cells[2].TagObject = (long) 11; // we use the actual number for sorting, not the string item.Cells[3].TagObject = (long) 233; item = sftTree1.ItemCollection.Add(new string[] { "Text 4", "Data 34", "144", "551" }); item.Cells[2].TagObject = (long) 144; // we use the actual number for sorting, not the string item.Cells[3].TagObject = (long) 551; SetSorted(0); // remember that column 0 is (already) sorted sftTree1.Columns.MakeOptimal(0, false); sftTree1.RecalcHorizontalExtent(); sftTree1.Initializing = false; } private int m_sortedColumn = -1; // remembers the sorted column private bool SetSorted(int column) { bool fAscending = true; // assume new column will be ascending if (m_sortedColumn == column && sftTree1.Headers[0, column].SortStatus == SortStatusEnum.Ascending) fAscending = false; // the current column is now descending // turn off sorting indicator in all column headers sftTree1.Headers.SetSortStatus(SortStatusEnum.NotSorted); // now set the new sorting indicator sftTree1.Headers[0, column].SortStatus = fAscending ? SortStatusEnum.Ascending : SortStatusEnum.Descending; m_sortedColumn = column; return fAscending; } private void SortData(ItemClickEventArgs e) { // sort the column last clicked if (e.Usage != UsageLocationEnum.header) // we are not interested if the click wasn't in the header return; if (e.Area != ItemClickAreaEnum.Cell) return; bool fAscending = SetSorted(e.Cell.ColumnIndex); switch (e.Cell.ColumnIndex) { default: // column 0 and 1 are sorted based on the Text property if (fAscending) sftTree1.ItemCollection.Sort(new SortAscending(e.Cell.ColumnIndex)); else sftTree1.ItemCollection.Sort(new SortDescending(e.Cell.ColumnIndex)); break; case 2: case 3: // column 2 and 3 are sorted based on the TagObject property, interpreted as a long if (fAscending) sftTree1.ItemCollection.Sort(new SortTagObjectAsLongAscending(e.Cell.ColumnIndex)); else sftTree1.ItemCollection.Sort(new SortTagObjectAsLongDescending(e.Cell.ColumnIndex)); break; } } public sealed class SortTagObjectAsLongAscending : IComparer { private int m_ColumnIndex; public SortTagObjectAsLongAscending(int ColumnIndex) { m_ColumnIndex = ColumnIndex; } public int Compare(object x, object y) { ItemClass i1 = (ItemClass)x; ItemClass i2 = (ItemClass)y; long l1 = (long) i1.Cells[m_ColumnIndex].TagObject; long l2 = (long) i2.Cells[m_ColumnIndex].TagObject; if (l1 > l2) return 1; if (l1 < l2) return -1; return 0; } } public sealed class SortTagObjectAsLongDescending : IComparer { private int m_ColumnIndex; public SortTagObjectAsLongDescending(int ColumnIndex) { m_ColumnIndex = ColumnIndex; } public int Compare(object x, object y) { ItemClass i1 = (ItemClass)x; ItemClass i2 = (ItemClass)y; long l1 = (long)i1.Cells[m_ColumnIndex].TagObject; long l2 = (long)i2.Cells[m_ColumnIndex].TagObject; if (l1 < l2) return 1; if (l1 > l2) return -1; return 0; } } // ItemClick event private void sftTree1_ItemClick(object sender, ItemClickEventArgs e) { Debug.Write("** ItemClick"); DumpValues(e); SortData(e); } private void sftTree1_ItemDoubleClick(object sender, ItemClickEventArgs e) { Debug.Write("** ItemDoubleClick"); DumpValues(e); SortData(e); } // This is a small helper routine to show all properties and fields of an object private void DumpValues(object o) { PropertyInfo[] api = o.GetType().GetProperties(); foreach (PropertyInfo pi in api) Debug.Write(" " + pi.Name + " " + pi.GetValue(o, new object[] { })); FieldInfo[] afi = o.GetType().GetFields(); foreach (FieldInfo fi in afi) Debug.Write(" " + fi.Name + " " + fi.GetValue(o)); Debug.WriteLine(""); } } }