PageRenderTime 77ms CodeModel.GetById 36ms RepoModel.GetById 0ms app.codeStats 2ms

/GDFlacToolVS2008/ObjectListView2010/ObjectListView.cs

http://gdflactool.codeplex.com
C# | 9414 lines | 4905 code | 1028 blank | 3481 comment | 1167 complexity | 7fdd2383b09bfde8c8e07b4391f45452 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * ObjectListView - A listview to show various aspects of a collection of objects
  3. *
  4. * Author: Phillip Piper
  5. * Date: 9/10/2006 11:15 AM
  6. *
  7. * Change log
  8. * 2012-05-06 JPP - Fix bug where collapsing the first group would cause decorations to stop being drawn (SR #3502608)
  9. * 2012-04-23 JPP - Trigger GroupExpandingCollapsing event to allow the expand/collapse to be cancelled
  10. * - Fixed SetGroupSpacing() so it corrects updates the space between all groups.
  11. * - ResizeLastGroup() now does nothing since it was broken and I can't remember what it was
  12. * even supposed to do :)
  13. * 2012-04-18 JPP - Upgraded hit testing to include hits on groups.
  14. * - HotItemChanged is now correctly recalculated on each mouse move. Includes "hot" group information.
  15. * 2012-04-14 JPP - Added GroupStateChanged event. Useful for knowing when a group is collapsed/expanded.
  16. * - Added AdditionalFilter property. This filter is combined with the Excel-like filtering that
  17. * the end user might enact at runtime.
  18. * 2012-04-10 JPP - Added PersistentCheckBoxes property to allow primary checkboxes to remember their values
  19. * across list rebuilds.
  20. * 2012-04-05 JPP - Reverted some code to .NET 2.0 standard.
  21. * - Tweaked some code
  22. * 2012-02-05 JPP - Fixed bug when selecting a separator on a drop down menu
  23. * 2011-06-24 JPP - Added CanUseApplicationIdle property to cover cases where Application.Idle events
  24. * are not triggered. For example, when used within VS (and probably Office) extensions
  25. * Application.Idle is never triggered. Set CanUseApplicationIdle to false to handle
  26. * these cases.
  27. * - Handle cases where a second tool tip is installed onto the ObjectListView.
  28. * - Correctly recolour rows after an Insert or Move
  29. * - Removed m.LParam cast which could cause overflow issues on Win7/64 bit.
  30. * v2.5.0
  31. * 2011-05-31 JPP - SelectObject() and SelectObjects() no longer deselect all other rows.
  32. Set the SelectedObject or SelectedObjects property to do that.
  33. * - Added CheckedObjectsEnumerable
  34. * - Made setting CheckedObjects more efficient on large collections
  35. * - Deprecated GetSelectedObject() and GetSelectedObjects()
  36. * 2011-04-25 JPP - Added SubItemChecking event
  37. * - Fixed bug in handling of NewValue on CellEditFinishing event
  38. * 2011-04-12 JPP - Added UseFilterIndicator
  39. * - Added some more localizable messages
  40. * 2011-04-10 JPP - FormatCellEventArgs now has a CellValue property, which is the model value displayed
  41. * by the cell. For example, for the Birthday column, the CellValue might be
  42. * DateTime(1980, 12, 31), whereas the cell's text might be 'Dec 31, 1980'.
  43. * 2011-04-04 JPP - Tweaked UseTranslucentSelection and UseTranslucentHotItem to look (a little) more
  44. * like Vista/Win7.
  45. * - Alternate colours are now only applied in Details view (as they always should have been)
  46. * - Alternate colours are now correctly recalculated after removing objects
  47. * 2011-03-29 JPP - Added SelectColumnsOnRightClickBehaviour to allow the selecting of columns mechanism
  48. * to be changed. Can now be InlineMenu (the default), SubMenu, or ModelDialog.
  49. * - ColumnSelectionForm was moved from the demo into the ObjectListView project itself.
  50. * - Ctrl-C copying is now able to use the DragSource to create the data transfer object.
  51. * 2011-03-19 JPP - All model object comparisons now use Equals rather than == (thanks to vulkanino)
  52. * - [Small Break] GetNextItem() and GetPreviousItem() now accept and return OLVListView
  53. * rather than ListViewItems.
  54. * 2011-03-07 JPP - [Big] Added Excel-style filtering. Right click on a header to show a Filtering menu.
  55. * - Added CellEditKeyEngine to allow key handling when cell editing to be completely customised.
  56. * Add CellEditTabChangesRows and CellEditEnterChangesRows to show some of these abilities.
  57. * 2011-03-06 JPP - Added OLVColumn.AutoCompleteEditorMode in preference to AutoCompleteEditor
  58. * (which is now just a wrapper). Thanks to Clive Haskins
  59. * - Added lots of docs to new classes
  60. * 2011-02-25 JPP - Preserve word wrap settings on TreeListView
  61. * - Resize last group to keep it on screen (thanks to ?)
  62. * 2010-11-16 JPP - Fixed (once and for all) DisplayIndex problem with Generator
  63. * - Changed the serializer used in SaveState()/RestoreState() so that it resolves on
  64. * class name alone.
  65. * - Fixed bug in GroupWithItemCountSingularFormatOrDefault
  66. * - Fixed strange flickering in grouped, owner drawn OLV's using RefreshObject()
  67. * v2.4.1
  68. * 2010-08-25 JPP - Fixed bug where setting OLVColumn.CheckBoxes to false gave it a renderer
  69. * specialized for checkboxes. Oddly, this made Generator created owner drawn
  70. * lists appear to be completely empty.
  71. * - In IDE, all ObjectListView properties are now in a single "ObjectListView" category,
  72. * rather than splitting them between "Appearance" and "Behavior" categories.
  73. * - Added GroupingParameters.GroupComparer to allow groups to be sorted in a customizable fashion.
  74. * - Sorting of items within a group can be disabled by setting
  75. * GroupingParameters.PrimarySortOrder to None.
  76. * 2010-08-24 JPP - Added OLVColumn.IsHeaderVertical to make a column draw its header vertical.
  77. * - Added OLVColumn.HeaderTextAlign to control the alignment of a column's header text.
  78. * - Added HeaderMaximumHeight to limit how tall the header section can become
  79. * 2010-08-18 JPP - Fixed long standing bug where having 0 columns caused a InvalidCast exception.
  80. * - Added IncludeAllColumnsInDataObject property
  81. * - Improved BuildList(bool) so that it preserves scroll position even when
  82. * the listview is grouped.
  83. * 2010-08-08 JPP - Added OLVColumn.HeaderImageKey to allow column headers to have an image.
  84. * - CellEdit validation and finish events now have NewValue property.
  85. * 2010-08-03 JPP - Subitem checkboxes improvments: obey IsEditable, can be hot, can be disabled.
  86. * - No more flickering of selection when tabbing between cells
  87. * - Added EditingCellBorderDecoration to make it clearer which cell is being edited.
  88. * 2010-08-01 JPP - Added ObjectListView.SmoothingMode to control the smoothing of all graphics
  89. * operations
  90. * - Columns now cache their group item format strings so that they still work as
  91. * grouping columns after they have been removed from the listview. This cached
  92. * value is only used when the column is not part of the listview.
  93. * 2010-07-25 JPP - Correctly trigger a Click event when the mouse is clicked.
  94. * 2010-07-16 JPP - Invalidate the control before and after cell editing to make sure it looks right
  95. * 2010-06-23 JPP - Right mouse clicks on checkboxes no longer confuse them
  96. * 2010-06-21 JPP - Avoid bug in underlying ListView control where virtual lists in SmallIcon view
  97. * generate GETTOOLINFO msgs with invalid item indicies.
  98. * - Fixed bug where FastObjectListView would throw an exception when showing hyperlinks
  99. * in any view except Details.
  100. * 2010-06-15 JPP - Fixed bug in ChangeToFilteredColumns() that resulted in column display order
  101. * being lost when a column was hidden.
  102. * - Renamed IsVista property to IsVistaOrLater which more accurately describes its function.
  103. * v2.4
  104. * 2010-04-14 JPP - Prevent object disposed errors when mouse event handlers cause the
  105. * ObjectListView to be destroyed (e.g. closing a form during a
  106. * double click event).
  107. * - Avoid checkbox munging bug in standard ListView when shift clicking on non-primary
  108. * columns when FullRowSelect is true.
  109. * 2010-04-12 JPP - Fixed bug in group sorting (thanks Mike).
  110. * 2010-04-07 JPP - Prevent hyperlink processing from triggering spurious MouseUp events.
  111. * This showed itself by launching the same url multiple times.
  112. * 2010-04-06 JPP - Space filling columns correctly resize upon initial display
  113. * - ShowHeaderInAllViews is better but still not working reliably.
  114. * See comments on property for more details.
  115. * 2010-03-23 JPP - Added ObjectListView.HeaderFormatStyle and OLVColumn.HeaderFormatStyle.
  116. * This makes HeaderFont and HeaderForeColor properties unnecessary --
  117. * they will be marked obsolete in the next version and removed after that.
  118. * 2010-03-16 JPP - Changed object checking so that objects can be pre-checked before they
  119. * are added to the list. Normal ObjectListViews managed "checkedness" in
  120. * the ListViewItem, so this won't work for them, unless check state getters
  121. * and putters have been installed. It will work on on virtual lists (thus fast lists and
  122. * tree views) since they manage their own check state.
  123. * 2010-03-06 JPP - Hide "Items" and "Groups" from the IDE properties grid since they shouldn't be set like that.
  124. * They can still be accessed through "Custom Commands" and there's nothing we can do
  125. * about that.
  126. * 2010-03-05 JPP - Added filtering
  127. * 2010-01-18 JPP - Overlays can be turned off. They also only work on 32-bit displays
  128. * v2.3
  129. * 2009-10-30 JPP - Plugged possible resource leak by using using() with CreateGraphics()
  130. * 2009-10-28 JPP - Fix bug when right clicking in the empty area of the header
  131. * 2009-10-20 JPP - Redraw the control after setting EmptyListMsg property
  132. * v2.3
  133. * 2009-09-30 JPP - Added Dispose() method to properly release resources
  134. * 2009-09-16 JPP - Added OwnerDrawnHeader, which you can set to true if you want to owner draw
  135. * the header yourself.
  136. * 2009-09-15 JPP - Added UseExplorerTheme, which allow complete visual compliance with Vista explorer.
  137. * But see property documentation for its many limitations.
  138. * - Added ShowHeaderInAllViews. To make this work, Columns are no longer
  139. * changed when switching to/from Tile view.
  140. * 2009-09-11 JPP - Added OLVColumn.AutoCompleteEditor to allow the autocomplete of cell editors
  141. * to be disabled.
  142. * 2009-09-01 JPP - Added ObjectListView.TextRenderingHint property which controls the
  143. * text rendering hint of all drawn text.
  144. * 2009-08-28 JPP - [BIG] Added group formatting to supercharge what is possible with groups
  145. * - [BIG] Virtual groups now work
  146. * - Extended MakeGroupies() to handle more aspects of group creation
  147. * 2009-08-19 JPP - Added ability to show basic column commands when header is right clicked
  148. * - Added SelectedRowDecoration, UseTranslucentSelection and UseTranslucentHotItem.
  149. * - Added PrimarySortColumn and PrimarySortOrder
  150. * 2009-08-15 JPP - Correct problems with standard hit test and subitems
  151. * 2009-08-14 JPP - [BIG] Support Decorations
  152. * - [BIG] Added header formatting capabilities: font, color, word wrap
  153. * - Gave ObjectListView its own designer to hide unwanted properties
  154. * - Separated design time stuff into separate file
  155. * - Added FormatRow and FormatCell events
  156. * 2009-08-09 JPP - Get around bug in HitTest when not FullRowSelect
  157. * - Added OLVListItem.GetSubItemBounds() method which works correctly
  158. * for all columns including column 0
  159. * 2009-08-07 JPP - Added Hot* properties that track where the mouse is
  160. * - Added HotItemChanged event
  161. * - Overrode TextAlign on columns so that column 0 can have something other
  162. * than just left alignment. This is only honored when owner drawn.
  163. * v2.2.1
  164. * 2009-08-03 JPP - Subitem edit rectangles always allowed for an image in the cell, even if there was none.
  165. * Now they only allow for an image when there actually is one.
  166. * - Added Bounds property to OLVListItem which handles items being part of collapsed groups.
  167. * 2009-07-29 JPP - Added GetSubItem() methods to ObjectListView and OLVListItem
  168. * 2009-07-26 JPP - Avoided bug in .NET framework involving column 0 of owner drawn listviews not being
  169. * redrawn when the listview was scrolled horizontally (this was a LOT of work to track
  170. * down and fix!)
  171. * - The cell edit rectangle is now correctly calculated when the listview is scrolled
  172. * horizontally.
  173. * 2009-07-14 JPP - If the user clicks/double clicks on a tree list cell, an edit operation will no longer begin
  174. * if the click was to the left of the expander. This is implemented in such a way that
  175. * other renderers can have similar "dead" zones.
  176. * 2009-07-11 JPP - CalculateCellBounds() messed with the FullRowSelect property, which confused the
  177. * tooltip handling on the underlying control. It no longer does this.
  178. * - The cell edit rectangle is now correctly calculated for owner-drawn, non-Details views.
  179. * 2009-07-08 JPP - Added Cell events (CellClicked, CellOver, CellRightClicked)
  180. * - Made BuildList(), AddObject() and RemoveObject() thread-safe
  181. * 2009-07-04 JPP - Space bar now properly toggles checkedness of selected rows
  182. * 2009-07-02 JPP - Fixed bug with tooltips when the underlying Windows control was destroyed.
  183. * - CellToolTipShowing events are now triggered in all views.
  184. * v2.2
  185. * 2009-06-02 JPP - BeforeSortingEventArgs now has a Handled property to let event handlers do
  186. * the item sorting themselves.
  187. * - AlwaysGroupByColumn works again, as does SortGroupItemsByPrimaryColumn and all their
  188. * various permutations.
  189. * - SecondarySortOrder and SecondarySortColumn are now "null" by default
  190. * 2009-05-15 JPP - Fixed bug so that KeyPress events are again triggered
  191. * 2009-05-10 JPP - Removed all unsafe code
  192. * 2009-05-07 JPP - Don't use glass panel for overlays when in design mode. It's too confusing.
  193. * 2009-05-05 JPP - Added Scroll event (thanks to Christophe Hosten for the complete patch to implement this)
  194. * - Added Unfocused foreground and background colors (also thanks to Christophe Hosten)
  195. * 2009-04-29 JPP - Added SelectedColumn property, which puts a slight tint on that column. Combine
  196. * this with TintSortColumn property and the sort column is automatically tinted.
  197. * - Use an overlay to implement "empty list" msg. Default empty list msg is now prettier.
  198. * 2009-04-28 JPP - Fixed bug where DoubleClick events were not triggered when CheckBoxes was true
  199. * 2009-04-23 JPP - Fixed various bugs under Vista.
  200. * - Made groups collapsible - Vista only. Thanks to Crustyapplesniffer.
  201. * - Forward events from DropSink to the control itself. This allows handlers to be defined
  202. * within the IDE for drop events
  203. * 2009-04-16 JPP - Made several properties localizable.
  204. * 2009-04-11 JPP - Correctly renderer checkboxes when RowHeight is non-standard
  205. * 2009-04-11 JPP - Implemented overlay architecture, based on CustomDraw scheme.
  206. * This unified drag drop feedback, empty list msgs and overlay images.
  207. * - Added OverlayImage and friends, which allows an image to be drawn
  208. * transparently over the listview
  209. * 2009-04-10 JPP - Fixed long-standing annoying flicker on owner drawn virtual lists!
  210. * This means, amongst other things, that grid lines no longer get confused,
  211. * and drag-select no longer flickers.
  212. * 2009-04-07 JPP - Calculate edit rectangles more accurately
  213. * 2009-04-06 JPP - Double-clicking no longer toggles the checkbox
  214. * - Double-clicking on a checkbox no longer confuses the checkbox
  215. * 2009-03-16 JPP - Optimized the build of autocomplete lists
  216. * v2.1
  217. * 2009-02-24 JPP - Fix bug where double-clicking VERY quickly on two different cells
  218. * could give two editors
  219. * - Maintain focused item when rebuilding list (SF #2547060)
  220. * 2009-02-22 JPP - Reworked checkboxes so that events are triggered for virtual lists
  221. * 2009-02-15 JPP - Added ObjectListView.ConfigureAutoComplete utility method
  222. * 2009-02-02 JPP - Fixed bug with AlwaysGroupByColumn where column header clicks would not resort groups.
  223. * 2009-02-01 JPP - OLVColumn.CheckBoxes and TriStateCheckBoxes now work.
  224. * 2009-01-28 JPP - Complete overhaul of renderers!
  225. * - Use IRenderer
  226. * - Added ObjectListView.ItemRenderer to draw whole items
  227. * 2009-01-23 JPP - Simple Checkboxes now work properly
  228. * - Added TriStateCheckBoxes property to control whether the user can
  229. * set the row checkbox to have the Indeterminate value
  230. * - CheckState property is now just a wrapper around the StateImageIndex property
  231. * 2009-01-20 JPP - Changed to always draw columns when owner drawn, rather than falling back on DrawDefault.
  232. * This simplified several owner drawn problems
  233. * - Added DefaultRenderer property to help with the above
  234. * - HotItem background color is applied to all cells even when FullRowSelect is false
  235. * - Allow grouping by CheckedAspectName columns
  236. * - Commented out experimental animations. Still needs work.
  237. * 2009-01-17 JPP - Added HotItemStyle and UseHotItem to highlight the row under the cursor
  238. * - Added UseCustomSelectionColors property
  239. * - Owner draw mode now honors ForeColor and BackColor settings on the list
  240. * 2009-01-16 JPP - Changed to use EditorRegistry rather than hard coding cell editors
  241. * 2009-01-10 JPP - Changed to use Equals() method rather than == to compare model objects.
  242. * v2.0.1
  243. * 2009-01-08 JPP - Fixed long-standing "multiple columns generated" problem.
  244. * Thanks to pinkjones for his help with solving this one!
  245. * - Added EnsureGroupVisible()
  246. * 2009-01-07 JPP - Made all public and protected methods virtual
  247. * - FinishCellEditing, PossibleFinishCellEditing and CancelCellEditing are now public
  248. * 2008-12-20 JPP - Fixed bug with group comparisons when a group key was null (SF#2445761)
  249. * 2008-12-19 JPP - Fixed bug with space filling columns and layout events
  250. * - Fixed RowHeight so that it only changes the row height, not the width of the images.
  251. * v2.0
  252. * 2008-12-10 JPP - Handle Backspace key. Resets the seach-by-typing state without delay
  253. * - Made some changes to the column collection editor to try and avoid
  254. * the multiple column generation problem.
  255. * - Updated some documentation
  256. * 2008-12-07 JPP - Search-by-typing now works when showing groups
  257. * - Added BeforeSearching and AfterSearching events which are triggered when the user types
  258. * into the list.
  259. * - Added secondary sort information to Before/AfterSorting events
  260. * - Reorganized group sorting code. Now triggers Sorting events.
  261. * - Added GetItemIndexInDisplayOrder()
  262. * - Tweaked in the interaction of the column editor with the IDE so that we (normally)
  263. * don't rely on a hack to find the owning ObjectListView
  264. * - Changed all 'DefaultValue(typeof(Color), "Empty")' to 'DefaultValue(typeof(Color), "")'
  265. * since the first does not given Color.Empty as I thought, but the second does.
  266. * 2008-11-28 JPP - Fixed long standing bug with horizontal scrollbar when shrinking the window.
  267. * (thanks to Bartosz Borowik)
  268. * 2008-11-25 JPP - Added support for dynamic tooltips
  269. * - Split out comparers and header controls stuff into their own files
  270. * 2008-11-21 JPP - Fixed bug where enabling grouping when there was not a sort column would not
  271. * produce a grouped list. Grouping column now defaults to column 0.
  272. * - Preserve selection on virtual lists when sorting
  273. * 2008-11-20 JPP - Added ability to search by sort column to ObjectListView. Unified this with
  274. * ability that was already in VirtualObjectListView
  275. * 2008-11-19 JPP - Fixed bug in ChangeToFilteredColumns() where DisplayOrder was not always restored correctly.
  276. * 2008-10-29 JPP - Event argument blocks moved to directly within the namespace, rather than being
  277. * nested inside ObjectListView class.
  278. * - Removed OLVColumn.CellEditor since it was never used.
  279. * - Marked OLVColumn.AspectGetterAutoGenerated as obsolete (it has not been used for
  280. * several versions now).
  281. * 2008-10-28 JPP - SelectedObjects is now an IList, rather than an ArrayList. This allows
  282. * it to accept generic list (eg List<File>).
  283. * 2008-10-09 JPP - Support indeterminate checkbox values.
  284. * [BREAKING CHANGE] CheckStateGetter/CheckStatePutter now use CheckState types only.
  285. * BooleanCheckStateGetter and BooleanCheckStatePutter added to ease transition.
  286. * 2008-10-08 JPP - Added setFocus parameter to SelectObject(), which allows focus to be set
  287. * at the same time as selecting.
  288. * 2008-09-27 JPP - BIG CHANGE: Fissioned this file into separate files for each component
  289. * 2008-09-24 JPP - Corrected bug with owner drawn lists where a column 0 with a renderer
  290. * would draw at column 0 even if column 0 was dragged to another position.
  291. * - Correctly handle space filling columns when columns are added/removed
  292. * 2008-09-16 JPP - Consistently use try..finally for BeginUpdate()/EndUpdate() pairs
  293. * 2008-08-24 JPP - If LastSortOrder is None when adding objects, don't force a resort.
  294. * 2008-08-22 JPP - Catch and ignore some problems with setting TopIndex on FastObjectListViews.
  295. * 2008-08-05 JPP - In the right-click column select menu, columns are now sorted by display order, rather than alphabetically
  296. * v1.13
  297. * 2008-07-23 JPP - Consistently use copy-on-write semantics with Add/RemoveObject methods
  298. * 2008-07-10 JPP - Enable validation on cell editors through a CellEditValidating event.
  299. * (thanks to Artiom Chilaru for the initial suggestion and implementation).
  300. * 2008-07-09 JPP - Added HeaderControl.Handle to allow OLV to be used within UserControls.
  301. * (thanks to Michael Coffey for tracking this down).
  302. * 2008-06-23 JPP - Split the more generally useful CopyObjectsToClipboard() method
  303. * out of CopySelectionToClipboard()
  304. * 2008-06-22 JPP - Added AlwaysGroupByColumn and AlwaysGroupBySortOrder, which
  305. * force the list view to always be grouped by a particular column.
  306. * 2008-05-31 JPP - Allow check boxes on FastObjectListViews
  307. * - Added CheckedObject and CheckedObjects properties
  308. * 2008-05-11 JPP - Allow selection foreground and background colors to be changed.
  309. * Windows doesn't allow this, so we can only make it happen when owner
  310. * drawing. Set the HighlightForegroundColor and HighlightBackgroundColor
  311. * properties and then call EnableCustomSelectionColors().
  312. * v1.12
  313. * 2008-05-08 JPP - Fixed bug where the column select menu would not appear if the
  314. * ObjectListView has a context menu installed.
  315. * 2008-05-05 JPP - Non detail views can now be owner drawn. The renderer installed for
  316. * primary column is given the chance to render the whole item.
  317. * See BusinessCardRenderer in the demo for an example.
  318. * - BREAKING CHANGE: RenderDelegate now returns a bool to indicate if default
  319. * rendering should be done. Previously returned void. Only important if your
  320. * code used RendererDelegate directly. Renderers derived from BaseRenderer
  321. * are unchanged.
  322. * 2008-05-03 JPP - Changed cell editing to use values directly when the values are Strings.
  323. * Previously, values were always handed to the AspectToStringConverter.
  324. * - When editing a cell, tabbing no longer tries to edit the next subitem
  325. * when not in details view!
  326. * 2008-05-02 JPP - MappedImageRenderer can now handle a Aspects that return a collection
  327. * of values. Each value will be drawn as its own image.
  328. * - Made AddObjects() and RemoveObjects() work for all flavours (or at least not crash)
  329. * - Fixed bug with clearing virtual lists that has been scrolled vertically
  330. * - Made TopItemIndex work with virtual lists.
  331. * 2008-05-01 JPP - Added AddObjects() and RemoveObjects() to allow faster mods to the list
  332. * - Reorganised public properties. Now alphabetical.
  333. * - Made the class ObjectListViewState internal, as it always should have been.
  334. * v1.11
  335. * 2008-04-29 JPP - Preserve scroll position when building the list or changing columns.
  336. * - Added TopItemIndex property. Due to problems with the underlying control, this
  337. * property is not always reliable. See property docs for info.
  338. * 2008-04-27 JPP - Added SelectedIndex property.
  339. * - Use a different, more general strategy to handle Invoke(). Removed all delegates
  340. * that were only declared to support Invoke().
  341. * - Check all native structures for 64-bit correctness.
  342. * 2008-04-25 JPP - Released on SourceForge.
  343. * 2008-04-13 JPP - Added ColumnRightClick event.
  344. * - Made the assembly CLS-compliant. To do this, our cell editors were made internal, and
  345. * the constraint on FlagRenderer template parameter was removed (the type must still
  346. * be an IConvertible, but if it isn't, the error will be caught at runtime, not compile time).
  347. * 2008-04-12 JPP - Changed HandleHeaderRightClick() to have a columnIndex parameter, which tells
  348. * exactly which column was right-clicked.
  349. * 2008-03-31 JPP - Added SaveState() and RestoreState()
  350. * - When cell editing, scrolling with a mouse wheel now ends the edit operation.
  351. * v1.10
  352. * 2008-03-25 JPP - Added space filling columns. See OLVColumn.FreeSpaceProportion property for details.
  353. * A space filling columns fills all (or a portion) of the width unoccupied by other columns.
  354. * 2008-03-23 JPP - Finished tinkering with support for Mono. Compile with conditional compilation symbol 'MONO'
  355. * to enable. On Windows, current problems with Mono:
  356. * - grid lines on virtual lists crashes
  357. * - when grouped, items sometimes are not drawn when any item is scrolled out of view
  358. * - i can't seem to get owner drawing to work
  359. * - when editing cell values, the editing controls always appear behind the listview,
  360. * where they function fine -- the user just can't see them :-)
  361. * 2008-03-16 JPP - Added some methods suggested by Chris Marlowe (thanks for the suggestions Chris)
  362. * - ClearObjects()
  363. * - GetCheckedObject(), GetCheckedObjects()
  364. * - GetItemAt() variation that gets both the item and the column under a point
  365. * 2008-02-28 JPP - Fixed bug with subitem colors when using OwnerDrawn lists and a RowFormatter.
  366. * v1.9.1
  367. * 2008-01-29 JPP - Fixed bug that caused owner-drawn virtual lists to use 100% CPU
  368. * - Added FlagRenderer to help draw bitwise-OR'ed flag values
  369. * 2008-01-23 JPP - Fixed bug (introduced in v1.9) that made alternate row colour with groups not quite right
  370. * - Ensure that DesignerSerializationVisibility.Hidden is set on all non-browsable properties
  371. * - Make sure that sort indicators are shown after changing which columns are visible
  372. * 2008-01-21 JPP - Added FastObjectListView
  373. * v1.9
  374. * 2008-01-18 JPP - Added IncrementalUpdate()
  375. * 2008-01-16 JPP - Right clicking on column header will allow the user to choose which columns are visible.
  376. * Set SelectColumnsOnRightClick to false to prevent this behaviour.
  377. * - Added ImagesRenderer to draw more than one images in a column
  378. * - Changed the positioning of the empty list m to use all the client area. Thanks to Matze.
  379. * 2007-12-13 JPP - Added CopySelectionToClipboard(). Ctrl-C invokes this method. Supports text
  380. * and HTML formats.
  381. * 2007-12-12 JPP - Added support for checkboxes via CheckStateGetter and CheckStatePutter properties.
  382. * - Made ObjectListView and OLVColumn into partial classes so that others can extend them.
  383. * 2007-12-09 JPP - Added ability to have hidden columns, i.e. columns that the ObjectListView knows
  384. * about but that are not visible to the user. Controlled by OLVColumn.IsVisible.
  385. * Added ColumnSelectionForm to the project to show how it could be used in an application.
  386. *
  387. * v1.8
  388. * 2007-11-26 JPP - Cell editing fully functional
  389. * 2007-11-21 JPP - Added SelectionChanged event. This event is triggered once when the
  390. * selection changes, no matter how many items are selected or deselected (in
  391. * contrast to SelectedIndexChanged which is called once for every row that
  392. * is selected or deselected). Thanks to lupokehl42 (Daniel) for his suggestions and
  393. * improvements on this idea.
  394. * 2007-11-19 JPP - First take at cell editing
  395. * 2007-11-17 JPP - Changed so that items within a group are not sorted if lastSortOrder == None
  396. * - Only call MakeSortIndicatorImages() if we haven't already made the sort indicators
  397. * (Corrected misspelling in the name of the method too)
  398. * 2007-11-06 JPP - Added ability to have secondary sort criteria when sorting
  399. * (SecondarySortColumn and SecondarySortOrder properties)
  400. * - Added SortGroupItemsByPrimaryColumn to allow group items to be sorted by the
  401. * primary column. Previous default was to sort by the grouping column.
  402. * v1.7
  403. * No big changes to this version but made to work with ListViewPrinter and released with it.
  404. *
  405. * 2007-11-05 JPP - Changed BaseRenderer to use DrawString() rather than TextRenderer, since TextRenderer
  406. * does not work when printing.
  407. * v1.6
  408. * 2007-11-03 JPP - Fixed some bugs in the rebuilding of DataListView.
  409. * 2007-10-31 JPP - Changed to use builtin sort indicators on XP and later. This also avoids alignment
  410. * problems on Vista. (thanks to gravybod for the suggestion and example implementation)
  411. * 2007-10-21 JPP - Added MinimumWidth and MaximumWidth properties to OLVColumn.
  412. * - Added ability for BuildList() to preserve selection. Calling BuildList() directly
  413. * tries to preserve selection; calling SetObjects() does not.
  414. * - Added SelectAll() and DeselectAll() methods. Useful for working with large lists.
  415. * 2007-10-08 JPP - Added GetNextItem() and GetPreviousItem(), which walk sequentially through the
  416. * listview items, even when the view is grouped.
  417. * - Added SelectedItem property
  418. * 2007-09-28 JPP - Optimized aspect-to-string conversion. BuildList() 15% faster.
  419. * - Added empty implementation of RefreshObjects() to VirtualObjectListView since
  420. * RefreshObjects() cannot work on virtual lists.
  421. * 2007-09-13 JPP - Corrected bug with custom sorter in VirtualObjectListView (thanks for mpgjunky)
  422. * 2007-09-07 JPP - Corrected image scaling bug in DrawAlignedImage() (thanks to krita970)
  423. * 2007-08-29 JPP - Allow item count labels on groups to be set per column (thanks to cmarlow for idea)
  424. * 2007-08-14 JPP - Major rework of DataListView based on Ian Griffiths's great work
  425. * 2007-08-11 JPP - When empty, the control can now draw a "List Empty" m
  426. * - Added GetColumn() and GetItem() methods
  427. * v1.5
  428. * 2007-08-03 JPP - Support animated GIFs in ImageRenderer
  429. * - Allow height of rows to be specified - EXPERIMENTAL!
  430. * 2007-07-26 JPP - Optimised redrawing of owner-drawn lists by remembering the update rect
  431. * - Allow sort indicators to be turned off
  432. * 2007-06-30 JPP - Added RowFormatter delegate
  433. * - Allow a different label when there is only one item in a group (thanks to cmarlow)
  434. * v1.4
  435. * 2007-04-12 JPP - Allow owner drawn on steriods!
  436. * - Column headers now display sort indicators
  437. * - ImageGetter delegates can now return ints, strings or Images
  438. * (Images are only visible if the list is owner drawn)
  439. * - Added OLVColumn.MakeGroupies to help with group partitioning
  440. * - All normal listview views are now supported
  441. * - Allow dotted aspect names, e.g. Owner.Workgroup.Name (thanks to OlafD)
  442. * - Added SelectedObject and SelectedObjects properties
  443. * v1.3
  444. * 2007-03-01 JPP - Added DataListView
  445. * - Added VirtualObjectListView
  446. * - Added Freeze/Unfreeze capabilities
  447. * - Allowed sort handler to be installed
  448. * - Simplified sort comparisons: handles 95% of cases with only 6 lines of code!
  449. * - Fixed bug with alternative line colors on unsorted lists (thanks to cmarlow)
  450. * 2007-01-13 JPP - Fixed bug with lastSortOrder (thanks to Kwan Fu Sit)
  451. * - Non-OLVColumns are no longer allowed
  452. * 2007-01-04 JPP - Clear sorter before rebuilding list. 10x faster! (thanks to aaberg)
  453. * - Include GetField in GetAspectByName() so field values can be Invoked too.
  454. * - Fixed subtle bug in RefreshItem() that erased background colors.
  455. * 2006-11-01 JPP - Added alternate line colouring
  456. * 2006-10-20 JPP - Refactored all sorting comparisons and made it extendable. See ComparerManager.
  457. * - Improved IDE integration
  458. * - Made control DoubleBuffered
  459. * - Added object selection methods
  460. * 2006-10-13 JPP Implemented grouping and column sorting
  461. * 2006-10-09 JPP Initial version
  462. *
  463. * TO DO:
  464. * - Support undocumented group features: subseted groups, group footer items
  465. *
  466. * Copyright (C) 2006-2012 Phillip Piper
  467. *
  468. * This program is free software: you can redistribute it and/or modify
  469. * it under the terms of the GNU General Public License as published by
  470. * the Free Software Foundation, either version 3 of the License, or
  471. * (at your option) any later version.
  472. *
  473. * This program is distributed in the hope that it will be useful,
  474. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  475. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  476. * GNU General Public License for more details.
  477. *
  478. * You should have received a copy of the GNU General Public License
  479. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  480. *
  481. * If you wish to use this code in a closed source application, please contact phillip_piper@bigfoot.com.
  482. */
  483. using System;
  484. using System.Collections;
  485. using System.Collections.Generic;
  486. using System.ComponentModel;
  487. using System.Diagnostics;
  488. using System.Drawing;
  489. using System.Globalization;
  490. using System.IO;
  491. using System.Reflection;
  492. using System.Runtime.InteropServices;
  493. using System.Runtime.Serialization.Formatters.Binary;
  494. using System.Windows.Forms;
  495. using System.Windows.Forms.VisualStyles;
  496. using System.Runtime.Serialization.Formatters;
  497. using System.Threading;
  498. namespace BrightIdeasSoftware
  499. {
  500. /// <summary>
  501. /// An ObjectListView is a much easier to use, and much more powerful, version of the ListView.
  502. /// </summary>
  503. /// <remarks>
  504. /// <para>
  505. /// An ObjectListView automatically populates a ListView control with information taken
  506. /// from a given collection of objects. It can do this because each column is configured
  507. /// to know which bit of the model object (the "aspect") it should be displaying. Columns similarly
  508. /// understand how to sort the list based on their aspect, and how to construct groups
  509. /// using their aspect.
  510. /// </para>
  511. /// <para>
  512. /// Aspects are extracted by giving the name of a method to be called or a
  513. /// property to be fetched. These names can be simple names or they can be dotted
  514. /// to chain property access e.g. "Owner.Address.Postcode".
  515. /// Aspects can also be extracted by installing a delegate.
  516. /// </para>
  517. /// <para>
  518. /// An ObjectListView can show a "this list is empty" message when there is nothing to show in the list,
  519. /// so that the user knows the control is supposed to be empty.
  520. /// </para>
  521. /// <para>
  522. /// Right clicking on a column header should present a menu which can contain:
  523. /// commands (sort, group, ungroup); filtering; and column selection. Whether these
  524. /// parts of the menu appear is controlled by ShowCommandMenuOnRightClick,
  525. /// ShowFilterMenuOnRightClick and SelectColumnsOnRightClick respectively.
  526. /// </para>
  527. /// <para>
  528. /// The groups created by an ObjectListView can be configured to include other formatting
  529. /// information, including a group icon, subtitle and task button. Using some undocumented
  530. /// interfaces, these groups can even on virtual lists.
  531. /// </para>
  532. /// <para>
  533. /// ObjectListView supports dragging rows to other places, including other application.
  534. /// Special support is provide for drops from other ObjectListViews in the same application.
  535. /// In many cases, an ObjectListView becomes a full drag source by setting <see cref="IsSimpleDragSource"/> to
  536. /// true. Similarly, to accept drops, it is usually enough to set <see cref="IsSimpleDropSink"/> to true,
  537. /// and then handle the <see cref="CanDrop"/> and <see cref="Dropped"/> events (or the <see cref="ModelCanDrop"/> and
  538. /// <see cref="ModelDropped"/> events, if you only want to handle drops from other ObjectListViews in your application).
  539. /// </para>
  540. /// <para>
  541. /// For these classes to build correctly, the project must have references to these assemblies:
  542. /// </para>
  543. /// <list type="bullet">
  544. /// <item><description>System</description></item>
  545. /// <item><description>System.Data</description></item>
  546. /// <item><description>System.Design</description></item>
  547. /// <item><description>System.Drawing</description></item>
  548. /// <item><description>System.Windows.Forms (obviously)</description></item>
  549. /// </list>
  550. /// </remarks>
  551. [Designer(typeof(BrightIdeasSoftware.Design.ObjectListViewDesigner))]
  552. public partial class ObjectListView : ListView, ISupportInitialize {
  553. #region Life and death
  554. /// <summary>
  555. /// Create an ObjectListView
  556. /// </summary>
  557. public ObjectListView() {
  558. this.ColumnClick += new ColumnClickEventHandler(this.HandleColumnClick);
  559. this.Layout += new LayoutEventHandler(this.HandleLayout);
  560. this.ColumnWidthChanging += new ColumnWidthChangingEventHandler(this.HandleColumnWidthChanging);
  561. this.ColumnWidthChanged += new ColumnWidthChangedEventHandler(this.HandleColumnWidthChanged);
  562. base.View = View.Details;
  563. this.DoubleBuffered = true; // kill nasty flickers. hiss... me hates 'em
  564. this.ShowSortIndicators = true;
  565. // Setup the overlays that will be controlled by the IDE settings
  566. this.InitializeStandardOverlays();
  567. this.InitializeEmptyListMsgOverlay();
  568. }
  569. /// <summary>
  570. /// Dispose of any resources this instance has been using
  571. /// </summary>
  572. /// <param name="disposing"></param>
  573. protected override void Dispose(bool disposing) {
  574. base.Dispose(disposing);
  575. if (disposing) {
  576. foreach (GlassPanelForm glassPanel in this.glassPanels) {
  577. glassPanel.Unbind();
  578. glassPanel.Dispose();
  579. }
  580. this.glassPanels.Clear();
  581. }
  582. }
  583. #endregion
  584. #region Static properties
  585. /// <summary>
  586. /// Gets whether the program running on Vista or later?
  587. /// </summary>
  588. static public bool IsVistaOrLater {
  589. get {
  590. if (!ObjectListView.isVistaOrLater.HasValue)
  591. ObjectListView.isVistaOrLater = Environment.OSVersion.Version.Major >= 6;
  592. return ObjectListView.isVistaOrLater.Value;
  593. }
  594. }
  595. static private bool? isVistaOrLater;
  596. /// <summary>
  597. /// Gets whether the program running on Win7 or later?
  598. /// </summary>
  599. static public bool IsWin7OrLater {
  600. get {
  601. if (!ObjectListView.isWin7OrLater.HasValue) {
  602. // For some reason, Win7 is v6.1, not v7.0
  603. Version version = Environment.OSVersion.Version;
  604. ObjectListView.isWin7OrLater = version.Major > 6 || (version.Major == 6 && version.Minor > 0);
  605. }
  606. return ObjectListView.isWin7OrLater.Value;
  607. }
  608. }
  609. static private bool? isWin7OrLater;
  610. /// <summary>
  611. /// Gets or sets how what smoothing mode will be applied to graphic operations.
  612. /// </summary>
  613. static public System.Drawing.Drawing2D.SmoothingMode SmoothingMode {
  614. get { return ObjectListView.smoothingMode; }
  615. set { ObjectListView.smoothingMode = value; }
  616. }
  617. static private System.Drawing.Drawing2D.SmoothingMode smoothingMode =
  618. System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  619. /// <summary>
  620. /// Gets or sets how should text be renderered.
  621. /// </summary>
  622. static public System.Drawing.Text.TextRenderingHint TextRenderingHint {
  623. get { return ObjectListView.textRendereringHint; }
  624. set { ObjectListView.textRendereringHint = value; }
  625. }
  626. static private System.Drawing.Text.TextRenderingHint textRendereringHint =
  627. System.Drawing.Text.TextRenderingHint.SystemDefault;
  628. /// <summary>
  629. /// Convert the given enumerable into an ArrayList as efficiently as possible
  630. /// </summary>
  631. /// <param name="collection">The source collection</param>
  632. /// <param name="alwaysCreate">If true, this method will always create a new
  633. /// collection.</param>
  634. /// <returns>An ArrayList with the same contents as the given collection.</returns>
  635. /// <remarks>
  636. /// <para>When we move to .NET 3.5, we can use LINQ and not need this method.</para>
  637. /// </remarks>
  638. public static ArrayList EnumerableToArray(IEnumerable collection, bool alwaysCreate) {
  639. if (collection == null)
  640. return new ArrayList();
  641. if (!alwaysCreate) {
  642. ArrayList array = collection as ArrayList;
  643. if (array != null)
  644. return array;
  645. IList iList = collection as IList;
  646. if (iList != null)
  647. return ArrayList.Adapter(iList);
  648. }
  649. ICollection iCollection = collection as ICollection;
  650. if (iCollection != null)
  651. return new ArrayList(iCollection);
  652. ArrayList newObjects = new ArrayList();
  653. foreach (object x in collection)
  654. newObjects.Add(x);
  655. return newObjects;
  656. }
  657. /// <summary>
  658. /// Gets or sets whether all ObjectListViews will silently ignore missing aspect errors.
  659. /// </summary>
  660. /// <remarks>
  661. /// <para>
  662. /// By default, if an ObjectListView is asked to display an aspect
  663. /// (i.e. a field/property/method)
  664. /// that does not exist from a model, it displays an error message in that cell, since that
  665. /// condition is normally a programming error. There are some use cases where
  666. /// this is not an error -- in those cases, set this to true and ObjectListView will
  667. /// simply display an empty cell.
  668. /// </para>
  669. /// <para>Be warned: if you set this to true, it can be very difficult to track down
  670. /// typing mistakes or name changes in AspectNames.</para>
  671. /// </remarks>
  672. public static bool IgnoreMissingAspects {
  673. get { return Munger.IgnoreMissingAspects; }
  674. set { Munger.IgnoreMissingAspects = value; }
  675. }
  676. #endregion
  677. #region Public properties
  678. /// <summary>
  679. /// Gets or sets an model filter that is combined with any column filtering that the end-user specifies.
  680. /// </summary>
  681. /// <remarks>This is different from the ModelFilter property, since setting that will replace
  682. /// any column filtering, whereas setting this will combine this filter with the column filtering</remarks>
  683. [Browsable(false),
  684. DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  685. public virtual IModelFilter AdditionalFilter
  686. {
  687. get { return this.additionalFilter; }
  688. set
  689. {
  690. if (this.additionalFilter == value)
  691. return;
  692. this.additionalFilter = value;
  693. this.UpdateColumnFiltering();
  694. }
  695. }
  696. private IModelFilter additionalFilter;
  697. /// <summary>
  698. /// Get or set all the columns that this control knows about.
  699. /// Only those columns where IsVisible is true will be seen by the user.
  700. /// </summary>
  701. /// <remarks>
  702. /// <para>
  703. /// If you want to add new columns programmatically, add them to
  704. /// AllColumns and then call RebuildColumns(). Normally, you do not have to
  705. /// deal with this property directly. Just use the IDE.
  706. /// </para>
  707. /// <para>If you do add or remove columns from the AllColumns collection,
  708. /// you have to call RebuildColumns() to make those changes take effect.</para>
  709. /// </remarks>
  710. [Browsable(false),
  711. DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  712. public virtual List<OLVColumn> AllColumns {
  713. get { return this.allColumns; }
  714. set { this.allColumns = value ?? new List<OLVColumn>(); }
  715. }
  716. private List<OLVColumn> allColumns = new List<OLVColumn>();
  717. /// <summary>
  718. /// Gets or sets the background color of every second row
  719. /// </summary>
  720. [Category("ObjectListView"),
  721. Description("If using alternate colors, what color should the background of alterate rows be?"),
  722. DefaultValue(typeof(Color), "")]
  723. public Color AlternateRowBackColor {
  724. get { return alternateRowBackColor; }
  725. set { alternateRowBackColor = value; }
  726. }
  727. private Color alternateRowBackColor = Color.Empty;
  728. /// <summary>
  729. /// Gets the alternate row background color that has been set, or the default color
  730. /// </summary>
  731. [Browsable(false)]
  732. public virtual Color AlternateRowBackColorOrDefault {
  733. get {
  734. return this.alternateRowBackColor == Color.Empt

Large files files are truncated, but you can click here to view the full file