2021-01-12 08:32:13 +00:00
/ *
* ObjectListView - A listview to show various aspects of a collection of objects
*
* Author : Phillip Piper
* Date : 9 / 10 / 2006 11 : 15 AM
*
* Change log
* v2 . 9.1
* 2015 - 12 - 30 JPP - Added CellRendererGetter to allow each cell to have a different renderer .
* - Obsolete properties are no longer code - gen ' ed .
*
* v2 . 9.0
* 2015 - 08 - 22 JPP - Allow selected row back / fore colours to be specified for each row
* - Renamed properties related to selection colours :
* - HighlightBackgroundColor - > SelectedBackColor
* - HighlightForegroundColor - > SelectedForeColor
* - UnfocusedHighlightBackgroundColor - > UnfocusedSelectedBackColor
* - UnfocusedHighlightForegroundColor - > UnfocusedSelectedForeColor
* - UseCustomSelectionColors is no longer used
* 2015 - 08 - 03 JPP - Added ObjectListView . CellEditFinished event
* - Added EditorRegistry . Unregister ( )
* 2015 - 07 - 08 JPP - All ObjectListViews are now OwnerDrawn by default . This allows all the great features
* of ObjectListView to work correctly at the slight cost of more processing at render time .
* It also avoids the annoying "hot item background ignored in column 0" behaviour that native
* ListView has . Programmers can still turn it back off if they wish .
* 2015 - 06 - 27 JPP - Yet another attempt to disable ListView ' s "shift click toggles checkboxes" behaviour .
* The last strategy ( fake right click ) worked , but had nasty side effects . This one works
* by intercepting a HITTEST message so that it fails . It no longer creates fake right mouse events .
* - Trigger SelectionChanged when filter is changed
* 2015 - 06 - 23 JPP - [ BIG ] Added support for Buttons
* 2015 - 06 - 22 JPP - Added OLVColumn . SearchValueGetter to allow the text used when text filtering to be customised
* - The default DefaultRenderer is now a HighlightTextRenderer , since that seems more generally useful
* 2015 - 06 - 17 JPP - Added FocusedObject property
* - Hot item is now always applied to the row even if FullRowSelect is false
* 2015 - 06 - 11 JPP - Added DefaultHotItemStyle property
* 2015 - 06 - 07 JPP - Added HeaderMinimumHeight property
* - Added ObjectListView . CellEditUsesWholeCell and OLVColumn . CellEditUsesWholeCell properties .
* 2015 - 05 - 15 JPP - Allow ImageGetter to return an Image ( which I can ' t believe didn ' t work from the beginning ! )
* 2015 - 04 - 27 JPP - Fix bug where setting View to LargeIcon in the designer was not persisted
* 2015 - 04 - 07 JPP - Ensure changes to row . Font in FormatRow are not wiped out by FormatCell ( SF # 141 )
*
* v2 . 8.1
* 2014 - 10 - 15 JPP - Added CellEditActivateMode . SingleClickAlways mode
* - Fire Filter event event if ModelFilter and ListFilter are null ( SF # 126 )
* - Fixed issue where single - click editing didn ' t work ( SF # 128 )
* v2 . 8.0
* 2014 - 10 - 11 JPP - Fixed some XP - only flicker issues
* 2014 - 09 - 26 JPP - Fixed intricate bug involving checkboxes on non - owner - drawn virtual lists .
* - Fixed long standing ( but previously unreported ) error on non - details virtual lists where
* users could not click on checkboxes .
* 2014 - 09 - 07 JPP - ( Major ) Added ability to have checkboxes in headers
* - CellOver events are raised when the mouse moves over the header . Set TriggerCellOverEventsWhenOverHeader
* to false to disable this behaviour .
* - Freeze / Unfreeze now use BeginUpdate / EndUpdate to disable Window level drawing
* - Changed default value of ObjectListView . HeaderUsesThemes from true to false . Too many people were
* being confused , trying to make something interesting appear in the header and nothing showing up
* 2014 - 08 - 04 JPP - Final attempt to fix the multiple hyperlink events being raised . This involves turning
* a NM_CLICK notification into a NM_RCLICK .
* 2014 - 05 - 21 JPP - ( Major ) Added ability to disable rows . DisabledObjects , DisableObjects ( ) , DisabledItemStyle .
* 2014 - 04 - 25 JPP - Fixed issue where virtual lists containing a single row didn ' t update hyperlinks on MouseOver
* - Added sanity check before BuildGroups ( )
* 2014 - 03 - 22 JPP - Fixed some subtle bugs resulting from misuse of TryGetValue ( )
* 2014 - 03 - 09 JPP - Added CollapsedGroups property
* - Several minor Resharper complaints quiesced .
* v2 . 7
* 2014 - 02 - 14 JPP - Fixed issue with ShowHeaderInAllViews ( another one ! ) where setting it to false caused the list to lose
* its other extended styles , leading to nasty flickering and worse .
* 2014 - 02 - 06 JPP - Fix issue on virtual lists where the filter was not correctly reapplied after columns were added or removed .
* - Made disposing of cell editors optional ( defaults to true ) . This allows controls to be cached and reused .
* - Bracketed column resizing with BeginUpdate / EndUpdate to smooth redraws ( thanks to Davide )
* 2014 - 02 - 01 JPP - Added static property ObjectListView . GroupTitleDefault to allow the default group title to be localised .
* 2013 - 09 - 24 JPP - Fixed issue in RefreshObjects ( ) when model objects overrode the Equals ( ) / GetHashCode ( ) methods .
* - Made sure get state checker were used when they should have been
* 2013 - 04 - 21 JPP - Clicking on a non - groupable column header when showing groups will now sort
* the group contents by that column .
* v2 . 6
* 2012 - 08 - 16 JPP - Added ObjectListView . EditModel ( ) - - a convenience method to start an edit operation on a model
* 2012 - 08 - 10 JPP - Don ' t trigger selection changed events during sorting / grouping or add / removing columns
* 2012 - 08 - 06 JPP - Don ' t start a cell edit operation when the user clicks on the background of a checkbox cell .
* - Honor values from the BeforeSorting event when calling a CustomSorter
* 2012 - 08 - 02 JPP - Added CellVerticalAlignment and CellPadding properties .
* 2012 - 07 - 04 JPP - Fixed issue with cell editing where the cell editing didn ' t finish until the first idle event .
* This meant that if you clicked and held on the scroll thumb to finish a cell edit , the editor
* wouldn ' t be removed until the mouse was released .
* 2012 - 07 - 03 JPP - Fixed issue with SingleClick cell edit mode where the cell editing would not begin until the
* mouse moved after the click .
* 2012 - 06 - 25 JPP - Fixed bug where removing a column from a LargeIcon or SmallIcon view would crash the control .
* 2012 - 06 - 15 JPP - Added Reset ( ) method , which definitively removes all rows * and * columns from an ObjectListView .
* 2012 - 06 - 11 JPP - Added FilteredObjects property which returns the collection of objects that survives any installed filters .
* 2012 - 06 - 04 JPP - [ Big ] Added UseNotifyPropertyChanged to allow OLV to listen for INotifyPropertyChanged events on models .
* 2012 - 05 - 30 JPP - Added static property ObjectListView . IgnoreMissingAspects . If this is set to true , all
* ObjectListViews will silently ignore missing aspect errors . Read the remarks to see why this would be useful .
* 2012 - 05 - 23 JPP - Setting UseFilterIndicator to true now sets HeaderUsesTheme to false .
* Also , changed default value of UseFilterIndicator to false . Previously , HeaderUsesTheme and UseFilterIndicator
* defaulted to true , which was pointless since when the HeaderUsesTheme is true , UseFilterIndicator does nothing .
* v2 . 5.1
* 2012 - 05 - 06 JPP - Fix bug where collapsing the first group would cause decorations to stop being drawn ( SR # 3502608 )
* 2012 - 04 - 23 JPP - Trigger GroupExpandingCollapsing event to allow the expand / collapse to be cancelled
* - Fixed SetGroupSpacing ( ) so it corrects updates the space between all groups .
* - ResizeLastGroup ( ) now does nothing since it was broken and I can ' t remember what it was
* even supposed to do : )
* 2012 - 04 - 18 JPP - Upgraded hit testing to include hits on groups .
* - HotItemChanged is now correctly recalculated on each mouse move . Includes "hot" group information .
* 2012 - 04 - 14 JPP - Added GroupStateChanged event . Useful for knowing when a group is collapsed / expanded .
* - Added AdditionalFilter property . This filter is combined with the Excel - like filtering that
* the end user might enact at runtime .
* 2012 - 04 - 10 JPP - Added PersistentCheckBoxes property to allow primary checkboxes to remember their values
* across list rebuilds .
* 2012 - 04 - 05 JPP - Reverted some code to . NET 2.0 standard .
* - Tweaked some code
* 2012 - 02 - 05 JPP - Fixed bug when selecting a separator on a drop down menu
* 2011 - 06 - 24 JPP - Added CanUseApplicationIdle property to cover cases where Application . Idle events
* are not triggered . For example , when used within VS ( and probably Office ) extensions
* Application . Idle is never triggered . Set CanUseApplicationIdle to false to handle
* these cases .
* - Handle cases where a second tool tip is installed onto the ObjectListView .
* - Correctly recolour rows after an Insert or Move
* - Removed m . LParam cast which could cause overflow issues on Win7 / 64 bit .
* v2 . 5.0
* 2011 - 05 - 31 JPP - SelectObject ( ) and SelectObjects ( ) no longer deselect all other rows .
Set the SelectedObject or SelectedObjects property to do that .
* - Added CheckedObjectsEnumerable
* - Made setting CheckedObjects more efficient on large collections
* - Deprecated GetSelectedObject ( ) and GetSelectedObjects ( )
* 2011 - 04 - 25 JPP - Added SubItemChecking event
* - Fixed bug in handling of NewValue on CellEditFinishing event
* 2011 - 04 - 12 JPP - Added UseFilterIndicator
* - Added some more localizable messages
* 2011 - 04 - 10 JPP - FormatCellEventArgs now has a CellValue property , which is the model value displayed
* by the cell . For example , for the Birthday column , the CellValue might be
* DateTime ( 1980 , 12 , 31 ) , whereas the cell ' s text might be ' Dec 31 , 1980 ' .
* 2011 - 04 - 04 JPP - Tweaked UseTranslucentSelection and UseTranslucentHotItem to look ( a little ) more
* like Vista / Win7 .
* - Alternate colours are now only applied in Details view ( as they always should have been )
* - Alternate colours are now correctly recalculated after removing objects
* 2011 - 03 - 29 JPP - Added SelectColumnsOnRightClickBehaviour to allow the selecting of columns mechanism
* to be changed . Can now be InlineMenu ( the default ) , SubMenu , or ModelDialog .
* - ColumnSelectionForm was moved from the demo into the ObjectListView project itself .
* - Ctrl - C copying is now able to use the DragSource to create the data transfer object .
* 2011 - 03 - 19 JPP - All model object comparisons now use Equals rather than = = ( thanks to vulkanino )
* - [ Small Break ] GetNextItem ( ) and GetPreviousItem ( ) now accept and return OLVListView
* rather than ListViewItems .
* 2011 - 03 - 07 JPP - [ Big ] Added Excel - style filtering . Right click on a header to show a Filtering menu .
* - Added CellEditKeyEngine to allow key handling when cell editing to be completely customised .
* Add CellEditTabChangesRows and CellEditEnterChangesRows to show some of these abilities .
* 2011 - 03 - 06 JPP - Added OLVColumn . AutoCompleteEditorMode in preference to AutoCompleteEditor
* ( which is now just a wrapper ) . Thanks to Clive Haskins
* - Added lots of docs to new classes
* 2011 - 02 - 25 JPP - Preserve word wrap settings on TreeListView
* - Resize last group to keep it on screen ( thanks to ? )
* 2010 - 11 - 16 JPP - Fixed ( once and for all ) DisplayIndex problem with Generator
* - Changed the serializer used in SaveState ( ) / RestoreState ( ) so that it resolves on
* class name alone .
* - Fixed bug in GroupWithItemCountSingularFormatOrDefault
* - Fixed strange flickering in grouped , owner drawn OLV ' s using RefreshObject ( )
* v2 . 4.1
* 2010 - 08 - 25 JPP - Fixed bug where setting OLVColumn . CheckBoxes to false gave it a renderer
* specialized for checkboxes . Oddly , this made Generator created owner drawn
* lists appear to be completely empty .
* - In IDE , all ObjectListView properties are now in a single "ObjectListView" category ,
* rather than splitting them between "Appearance" and "Behavior" categories .
* - Added GroupingParameters . GroupComparer to allow groups to be sorted in a customizable fashion .
* - Sorting of items within a group can be disabled by setting
* GroupingParameters . PrimarySortOrder to None .
* 2010 - 08 - 24 JPP - Added OLVColumn . IsHeaderVertical to make a column draw its header vertical .
* - Added OLVColumn . HeaderTextAlign to control the alignment of a column ' s header text .
* - Added HeaderMaximumHeight to limit how tall the header section can become
* 2010 - 08 - 18 JPP - Fixed long standing bug where having 0 columns caused a InvalidCast exception .
* - Added IncludeAllColumnsInDataObject property
* - Improved BuildList ( bool ) so that it preserves scroll position even when
* the listview is grouped .
* 2010 - 08 - 08 JPP - Added OLVColumn . HeaderImageKey to allow column headers to have an image .
* - CellEdit validation and finish events now have NewValue property .
* 2010 - 08 - 03 JPP - Subitem checkboxes improvements : obey IsEditable , can be hot , can be disabled .
* - No more flickering of selection when tabbing between cells
* - Added EditingCellBorderDecoration to make it clearer which cell is being edited .
* 2010 - 08 - 01 JPP - Added ObjectListView . SmoothingMode to control the smoothing of all graphics
* operations
* - Columns now cache their group item format strings so that they still work as
* grouping columns after they have been removed from the listview . This cached
* value is only used when the column is not part of the listview .
* 2010 - 07 - 25 JPP - Correctly trigger a Click event when the mouse is clicked .
* 2010 - 07 - 16 JPP - Invalidate the control before and after cell editing to make sure it looks right
* 2010 - 06 - 23 JPP - Right mouse clicks on checkboxes no longer confuse them
* 2010 - 06 - 21 JPP - Avoid bug in underlying ListView control where virtual lists in SmallIcon view
* generate GETTOOLINFO msgs with invalid item indices .
* - Fixed bug where FastObjectListView would throw an exception when showing hyperlinks
* in any view except Details .
* 2010 - 06 - 15 JPP - Fixed bug in ChangeToFilteredColumns ( ) that resulted in column display order
* being lost when a column was hidden .
* - Renamed IsVista property to IsVistaOrLater which more accurately describes its function .
* v2 . 4
* 2010 - 04 - 14 JPP - Prevent object disposed errors when mouse event handlers cause the
* ObjectListView to be destroyed ( e . g . closing a form during a
* double click event ) .
* - Avoid checkbox munging bug in standard ListView when shift clicking on non - primary
* columns when FullRowSelect is true .
* 2010 - 04 - 12 JPP - Fixed bug in group sorting ( thanks Mike ) .
* 2010 - 04 - 07 JPP - Prevent hyperlink processing from triggering spurious MouseUp events .
* This showed itself by launching the same url multiple times .
* 2010 - 04 - 06 JPP - Space filling columns correctly resize upon initial display
* - ShowHeaderInAllViews is better but still not working reliably .
* See comments on property for more details .
* 2010 - 03 - 23 JPP - Added ObjectListView . HeaderFormatStyle and OLVColumn . HeaderFormatStyle .
* This makes HeaderFont and HeaderForeColor properties unnecessary - -
* they will be marked obsolete in the next version and removed after that .
* 2010 - 03 - 16 JPP - Changed object checking so that objects can be pre - checked before they
* are added to the list . Normal ObjectListViews managed "checkedness" in
* the ListViewItem , so this won ' t work for them , unless check state getters
* and putters have been installed . It will work on on virtual lists ( thus fast lists and
* tree views ) since they manage their own check state .
* 2010 - 03 - 06 JPP - Hide "Items" and "Groups" from the IDE properties grid since they shouldn ' t be set like that .
* They can still be accessed through "Custom Commands" and there ' s nothing we can do
* about that .
* 2010 - 03 - 05 JPP - Added filtering
* 2010 - 01 - 18 JPP - Overlays can be turned off . They also only work on 32 - bit displays
* v2 . 3
* 2009 - 10 - 30 JPP - Plugged possible resource leak by using using ( ) with CreateGraphics ( )
* 2009 - 10 - 28 JPP - Fix bug when right clicking in the empty area of the header
* 2009 - 10 - 20 JPP - Redraw the control after setting EmptyListMsg property
* v2 . 3
* 2009 - 09 - 30 JPP - Added Dispose ( ) method to properly release resources
* 2009 - 09 - 16 JPP - Added OwnerDrawnHeader , which you can set to true if you want to owner draw
* the header yourself .
* 2009 - 09 - 15 JPP - Added UseExplorerTheme , which allow complete visual compliance with Vista explorer .
* But see property documentation for its many limitations .
* - Added ShowHeaderInAllViews . To make this work , Columns are no longer
* changed when switching to / from Tile view .
* 2009 - 09 - 11 JPP - Added OLVColumn . AutoCompleteEditor to allow the autocomplete of cell editors
* to be disabled .
* 2009 - 09 - 01 JPP - Added ObjectListView . TextRenderingHint property which controls the
* text rendering hint of all drawn text .
* 2009 - 08 - 28 JPP - [ BIG ] Added group formatting to supercharge what is possible with groups
* - [ BIG ] Virtual groups now work
* - Extended MakeGroupies ( ) to handle more aspects of group creation
* 2009 - 08 - 19 JPP - Added ability to show basic column commands when header is right clicked
* - Added SelectedRowDecoration , UseTranslucentSelection and UseTranslucentHotItem .
* - Added PrimarySortColumn and PrimarySortOrder
* 2009 - 08 - 15 JPP - Correct problems with standard hit test and subitems
* 2009 - 08 - 14 JPP - [ BIG ] Support Decorations
* - [ BIG ] Added header formatting capabilities : font , color , word wrap
* - Gave ObjectListView its own designer to hide unwanted properties
* - Separated design time stuff into separate file
* - Added FormatRow and FormatCell events
* 2009 - 08 - 09 JPP - Get around bug in HitTest when not FullRowSelect
* - Added OLVListItem . GetSubItemBounds ( ) method which works correctly
* for all columns including column 0
* 2009 - 08 - 07 JPP - Added Hot * properties that track where the mouse is
* - Added HotItemChanged event
* - Overrode TextAlign on columns so that column 0 can have something other
* than just left alignment . This is only honored when owner drawn .
* v2 . 2.1
* 2009 - 08 - 03 JPP - Subitem edit rectangles always allowed for an image in the cell , even if there was none .
* Now they only allow for an image when there actually is one .
* - Added Bounds property to OLVListItem which handles items being part of collapsed groups .
* 2009 - 07 - 29 JPP - Added GetSubItem ( ) methods to ObjectListView and OLVListItem
* 2009 - 07 - 26 JPP - Avoided bug in . NET framework involving column 0 of owner drawn listviews not being
* redrawn when the listview was scrolled horizontally ( this was a LOT of work to track
* down and fix ! )
* - The cell edit rectangle is now correctly calculated when the listview is scrolled
* horizontally .
* 2009 - 07 - 14 JPP - If the user clicks / double clicks on a tree list cell , an edit operation will no longer begin
* if the click was to the left of the expander . This is implemented in such a way that
* other renderers can have similar "dead" zones .
* 2009 - 07 - 11 JPP - CalculateCellBounds ( ) messed with the FullRowSelect property , which confused the
* tooltip handling on the underlying control . It no longer does this .
* - The cell edit rectangle is now correctly calculated for owner - drawn , non - Details views .
* 2009 - 07 - 08 JPP - Added Cell events ( CellClicked , CellOver , CellRightClicked )
* - Made BuildList ( ) , AddObject ( ) and RemoveObject ( ) thread - safe
* 2009 - 07 - 04 JPP - Space bar now properly toggles checkedness of selected rows
* 2009 - 07 - 02 JPP - Fixed bug with tooltips when the underlying Windows control was destroyed .
* - CellToolTipShowing events are now triggered in all views .
* v2 . 2
* 2009 - 06 - 02 JPP - BeforeSortingEventArgs now has a Handled property to let event handlers do
* the item sorting themselves .
* - AlwaysGroupByColumn works again , as does SortGroupItemsByPrimaryColumn and all their
* various permutations .
* - SecondarySortOrder and SecondarySortColumn are now "null" by default
* 2009 - 05 - 15 JPP - Fixed bug so that KeyPress events are again triggered
* 2009 - 05 - 10 JPP - Removed all unsafe code
* 2009 - 05 - 07 JPP - Don ' t use glass panel for overlays when in design mode . It ' s too confusing .
* 2009 - 05 - 05 JPP - Added Scroll event ( thanks to Christophe Hosten for the complete patch to implement this )
* - Added Unfocused foreground and background colors ( also thanks to Christophe Hosten )
* 2009 - 04 - 29 JPP - Added SelectedColumn property , which puts a slight tint on that column . Combine
* this with TintSortColumn property and the sort column is automatically tinted .
* - Use an overlay to implement "empty list" msg . Default empty list msg is now prettier .
* 2009 - 04 - 28 JPP - Fixed bug where DoubleClick events were not triggered when CheckBoxes was true
* 2009 - 04 - 23 JPP - Fixed various bugs under Vista .
* - Made groups collapsible - Vista only . Thanks to Crustyapplesniffer .
* - Forward events from DropSink to the control itself . This allows handlers to be defined
* within the IDE for drop events
* 2009 - 04 - 16 JPP - Made several properties localizable .
* 2009 - 04 - 11 JPP - Correctly renderer checkboxes when RowHeight is non - standard
* 2009 - 04 - 11 JPP - Implemented overlay architecture , based on CustomDraw scheme .
* This unified drag drop feedback , empty list msgs and overlay images .
* - Added OverlayImage and friends , which allows an image to be drawn
* transparently over the listview
* 2009 - 04 - 10 JPP - Fixed long - standing annoying flicker on owner drawn virtual lists !
* This means , amongst other things , that grid lines no longer get confused ,
* and drag - select no longer flickers .
* 2009 - 04 - 07 JPP - Calculate edit rectangles more accurately
* 2009 - 04 - 06 JPP - Double - clicking no longer toggles the checkbox
* - Double - clicking on a checkbox no longer confuses the checkbox
* 2009 - 03 - 16 JPP - Optimized the build of autocomplete lists
* v2 . 1
* 2009 - 02 - 24 JPP - Fix bug where double - clicking VERY quickly on two different cells
* could give two editors
* - Maintain focused item when rebuilding list ( SF # 2547060 )
* 2009 - 02 - 22 JPP - Reworked checkboxes so that events are triggered for virtual lists
* 2009 - 02 - 15 JPP - Added ObjectListView . ConfigureAutoComplete utility method
* 2009 - 02 - 02 JPP - Fixed bug with AlwaysGroupByColumn where column header clicks would not resort groups .
* 2009 - 02 - 01 JPP - OLVColumn . CheckBoxes and TriStateCheckBoxes now work .
* 2009 - 01 - 28 JPP - Complete overhaul of renderers !
* - Use IRenderer
* - Added ObjectListView . ItemRenderer to draw whole items
* 2009 - 01 - 23 JPP - Simple Checkboxes now work properly
* - Added TriStateCheckBoxes property to control whether the user can
* set the row checkbox to have the Indeterminate value
* - CheckState property is now just a wrapper around the StateImageIndex property
* 2009 - 01 - 20 JPP - Changed to always draw columns when owner drawn , rather than falling back on DrawDefault .
* This simplified several owner drawn problems
* - Added DefaultRenderer property to help with the above
* - HotItem background color is applied to all cells even when FullRowSelect is false
* - Allow grouping by CheckedAspectName columns
* - Commented out experimental animations . Still needs work .
* 2009 - 01 - 17 JPP - Added HotItemStyle and UseHotItem to highlight the row under the cursor
* - Added UseCustomSelectionColors property
* - Owner draw mode now honors ForeColor and BackColor settings on the list
* 2009 - 01 - 16 JPP - Changed to use EditorRegistry rather than hard coding cell editors
* 2009 - 01 - 10 JPP - Changed to use Equals ( ) method rather than = = to compare model objects .
* v2 . 0.1
* 2009 - 01 - 08 JPP - Fixed long - standing "multiple columns generated" problem .
* Thanks to pinkjones for his help with solving this one !
* - Added EnsureGroupVisible ( )
* 2009 - 01 - 07 JPP - Made all public and protected methods virtual
* - FinishCellEditing , PossibleFinishCellEditing and CancelCellEditing are now public
* 2008 - 12 - 20 JPP - Fixed bug with group comparisons when a group key was null ( SF # 2445761 )
* 2008 - 12 - 19 JPP - Fixed bug with space filling columns and layout events
* - Fixed RowHeight so that it only changes the row height , not the width of the images .
* v2 . 0
* 2008 - 12 - 10 JPP - Handle Backspace key . Resets the search - by - typing state without delay
* - Made some changes to the column collection editor to try and avoid
* the multiple column generation problem .
* - Updated some documentation
* 2008 - 12 - 07 JPP - Search - by - typing now works when showing groups
* - Added BeforeSearching and AfterSearching events which are triggered when the user types
* into the list .
* - Added secondary sort information to Before / AfterSorting events
* - Reorganized group sorting code . Now triggers Sorting events .
* - Added GetItemIndexInDisplayOrder ( )
* - Tweaked in the interaction of the column editor with the IDE so that we ( normally )
* don ' t rely on a hack to find the owning ObjectListView
* - Changed all ' DefaultValue ( typeof ( Color ) , "Empty" ) ' to ' DefaultValue ( typeof ( Color ) , "" ) '
* since the first does not given Color . Empty as I thought , but the second does .
* 2008 - 11 - 28 JPP - Fixed long standing bug with horizontal scrollbar when shrinking the window .
* ( thanks to Bartosz Borowik )
* 2008 - 11 - 25 JPP - Added support for dynamic tooltips
* - Split out comparers and header controls stuff into their own files
* 2008 - 11 - 21 JPP - Fixed bug where enabling grouping when there was not a sort column would not
* produce a grouped list . Grouping column now defaults to column 0.
* - Preserve selection on virtual lists when sorting
* 2008 - 11 - 20 JPP - Added ability to search by sort column to ObjectListView . Unified this with
* ability that was already in VirtualObjectListView
* 2008 - 11 - 19 JPP - Fixed bug in ChangeToFilteredColumns ( ) where DisplayOrder was not always restored correctly .
* 2008 - 10 - 29 JPP - Event argument blocks moved to directly within the namespace , rather than being
* nested inside ObjectListView class .
* - Removed OLVColumn . CellEditor since it was never used .
* - Marked OLVColumn . AspectGetterAutoGenerated as obsolete ( it has not been used for
* several versions now ) .
* 2008 - 10 - 28 JPP - SelectedObjects is now an IList , rather than an ArrayList . This allows
* it to accept generic list ( eg List < File > ) .
* 2008 - 10 - 09 JPP - Support indeterminate checkbox values .
* [ BREAKING CHANGE ] CheckStateGetter / CheckStatePutter now use CheckState types only .
* BooleanCheckStateGetter and BooleanCheckStatePutter added to ease transition .
* 2008 - 10 - 08 JPP - Added setFocus parameter to SelectObject ( ) , which allows focus to be set
* at the same time as selecting .
* 2008 - 09 - 27 JPP - BIG CHANGE : Fissioned this file into separate files for each component
* 2008 - 09 - 24 JPP - Corrected bug with owner drawn lists where a column 0 with a renderer
* would draw at column 0 even if column 0 was dragged to another position .
* - Correctly handle space filling columns when columns are added / removed
* 2008 - 09 - 16 JPP - Consistently use try . . finally for BeginUpdate ( ) / EndUpdate ( ) pairs
* 2008 - 08 - 24 JPP - If LastSortOrder is None when adding objects , don ' t force a resort .
* 2008 - 08 - 22 JPP - Catch and ignore some problems with setting TopIndex on FastObjectListViews .
* 2008 - 08 - 05 JPP - In the right - click column select menu , columns are now sorted by display order , rather than alphabetically
* v1 . 13
* 2008 - 07 - 23 JPP - Consistently use copy - on - write semantics with Add / RemoveObject methods
* 2008 - 07 - 10 JPP - Enable validation on cell editors through a CellEditValidating event .
* ( thanks to Artiom Chilaru for the initial suggestion and implementation ) .
* 2008 - 07 - 09 JPP - Added HeaderControl . Handle to allow OLV to be used within UserControls .
* ( thanks to Michael Coffey for tracking this down ) .
* 2008 - 06 - 23 JPP - Split the more generally useful CopyObjectsToClipboard ( ) method
* out of CopySelectionToClipboard ( )
* 2008 - 06 - 22 JPP - Added AlwaysGroupByColumn and AlwaysGroupBySortOrder , which
* force the list view to always be grouped by a particular column .
* 2008 - 05 - 31 JPP - Allow check boxes on FastObjectListViews
* - Added CheckedObject and CheckedObjects properties
* 2008 - 05 - 11 JPP - Allow selection foreground and background colors to be changed .
* Windows doesn ' t allow this , so we can only make it happen when owner
* drawing . Set the HighlightForegroundColor and HighlightBackgroundColor
* properties and then call EnableCustomSelectionColors ( ) .
* v1 . 12
* 2008 - 05 - 08 JPP - Fixed bug where the column select menu would not appear if the
* ObjectListView has a context menu installed .
* 2008 - 05 - 05 JPP - Non detail views can now be owner drawn . The renderer installed for
* primary column is given the chance to render the whole item .
* See BusinessCardRenderer in the demo for an example .
* - BREAKING CHANGE : RenderDelegate now returns a bool to indicate if default
* rendering should be done . Previously returned void . Only important if your
* code used RendererDelegate directly . Renderers derived from BaseRenderer
* are unchanged .
* 2008 - 05 - 03 JPP - Changed cell editing to use values directly when the values are Strings .
* Previously , values were always handed to the AspectToStringConverter .
* - When editing a cell , tabbing no longer tries to edit the next subitem
* when not in details view !
* 2008 - 05 - 02 JPP - MappedImageRenderer can now handle a Aspects that return a collection
* of values . Each value will be drawn as its own image .
* - Made AddObjects ( ) and RemoveObjects ( ) work for all flavours ( or at least not crash )
* - Fixed bug with clearing virtual lists that has been scrolled vertically
* - Made TopItemIndex work with virtual lists .
* 2008 - 05 - 01 JPP - Added AddObjects ( ) and RemoveObjects ( ) to allow faster mods to the list
* - Reorganised public properties . Now alphabetical .
* - Made the class ObjectListViewState internal , as it always should have been .
* v1 . 11
* 2008 - 04 - 29 JPP - Preserve scroll position when building the list or changing columns .
* - Added TopItemIndex property . Due to problems with the underlying control , this
* property is not always reliable . See property docs for info .
* 2008 - 04 - 27 JPP - Added SelectedIndex property .
* - Use a different , more general strategy to handle Invoke ( ) . Removed all delegates
* that were only declared to support Invoke ( ) .
* - Check all native structures for 64 - bit correctness .
* 2008 - 04 - 25 JPP - Released on SourceForge .
* 2008 - 04 - 13 JPP - Added ColumnRightClick event .
* - Made the assembly CLS - compliant . To do this , our cell editors were made internal , and
* the constraint on FlagRenderer template parameter was removed ( the type must still
* be an IConvertible , but if it isn ' t , the error will be caught at runtime , not compile time ) .
* 2008 - 04 - 12 JPP - Changed HandleHeaderRightClick ( ) to have a columnIndex parameter , which tells
* exactly which column was right - clicked .
* 2008 - 03 - 31 JPP - Added SaveState ( ) and RestoreState ( )
* - When cell editing , scrolling with a mouse wheel now ends the edit operation .
* v1 . 10
* 2008 - 03 - 25 JPP - Added space filling columns . See OLVColumn . FreeSpaceProportion property for details .
* A space filling columns fills all ( or a portion ) of the width unoccupied by other columns .
* 2008 - 03 - 23 JPP - Finished tinkering with support for Mono . Compile with conditional compilation symbol ' MONO '
* to enable . On Windows , current problems with Mono :
* - grid lines on virtual lists crashes
* - when grouped , items sometimes are not drawn when any item is scrolled out of view
* - i can ' t seem to get owner drawing to work
* - when editing cell values , the editing controls always appear behind the listview ,
* where they function fine - - the user just can ' t see them : - )
* 2008 - 03 - 16 JPP - Added some methods suggested by Chris Marlowe ( thanks for the suggestions Chris )
* - ClearObjects ( )
* - GetCheckedObject ( ) , GetCheckedObjects ( )
* - GetItemAt ( ) variation that gets both the item and the column under a point
* 2008 - 02 - 28 JPP - Fixed bug with subitem colors when using OwnerDrawn lists and a RowFormatter .
* v1 . 9.1
* 2008 - 01 - 29 JPP - Fixed bug that caused owner - drawn virtual lists to use 100 % CPU
* - Added FlagRenderer to help draw bitwise - OR ' ed flag values
* 2008 - 01 - 23 JPP - Fixed bug ( introduced in v1 . 9 ) that made alternate row colour with groups not quite right
* - Ensure that DesignerSerializationVisibility . Hidden is set on all non - browsable properties
* - Make sure that sort indicators are shown after changing which columns are visible
* 2008 - 01 - 21 JPP - Added FastObjectListView
* v1 . 9
* 2008 - 01 - 18 JPP - Added IncrementalUpdate ( )
* 2008 - 01 - 16 JPP - Right clicking on column header will allow the user to choose which columns are visible .
* Set SelectColumnsOnRightClick to false to prevent this behaviour .
* - Added ImagesRenderer to draw more than one images in a column
* - Changed the positioning of the empty list m to use all the client area . Thanks to Matze .
* 2007 - 12 - 13 JPP - Added CopySelectionToClipboard ( ) . Ctrl - C invokes this method . Supports text
* and HTML formats .
* 2007 - 12 - 12 JPP - Added support for checkboxes via CheckStateGetter and CheckStatePutter properties .
* - Made ObjectListView and OLVColumn into partial classes so that others can extend them .
* 2007 - 12 - 09 JPP - Added ability to have hidden columns , i . e . columns that the ObjectListView knows
* about but that are not visible to the user . Controlled by OLVColumn . IsVisible .
* Added ColumnSelectionForm to the project to show how it could be used in an application .
*
* v1 . 8
* 2007 - 11 - 26 JPP - Cell editing fully functional
* 2007 - 11 - 21 JPP - Added SelectionChanged event . This event is triggered once when the
* selection changes , no matter how many items are selected or deselected ( in
* contrast to SelectedIndexChanged which is called once for every row that
* is selected or deselected ) . Thanks to lupokehl42 ( Daniel ) for his suggestions and
* improvements on this idea .
* 2007 - 11 - 19 JPP - First take at cell editing
* 2007 - 11 - 17 JPP - Changed so that items within a group are not sorted if lastSortOrder = = None
* - Only call MakeSortIndicatorImages ( ) if we haven ' t already made the sort indicators
* ( Corrected misspelling in the name of the method too )
* 2007 - 11 - 06 JPP - Added ability to have secondary sort criteria when sorting
* ( SecondarySortColumn and SecondarySortOrder properties )
* - Added SortGroupItemsByPrimaryColumn to allow group items to be sorted by the
* primary column . Previous default was to sort by the grouping column .
* v1 . 7
* No big changes to this version but made to work with ListViewPrinter and released with it .
*
* 2007 - 11 - 05 JPP - Changed BaseRenderer to use DrawString ( ) rather than TextRenderer , since TextRenderer
* does not work when printing .
* v1 . 6
* 2007 - 11 - 03 JPP - Fixed some bugs in the rebuilding of DataListView .
* 2007 - 10 - 31 JPP - Changed to use builtin sort indicators on XP and later . This also avoids alignment
* problems on Vista . ( thanks to gravybod for the suggestion and example implementation )
* 2007 - 10 - 21 JPP - Added MinimumWidth and MaximumWidth properties to OLVColumn .
* - Added ability for BuildList ( ) to preserve selection . Calling BuildList ( ) directly
* tries to preserve selection ; calling SetObjects ( ) does not .
* - Added SelectAll ( ) and DeselectAll ( ) methods . Useful for working with large lists .
* 2007 - 10 - 08 JPP - Added GetNextItem ( ) and GetPreviousItem ( ) , which walk sequentially through the
* listview items , even when the view is grouped .
* - Added SelectedItem property
* 2007 - 09 - 28 JPP - Optimized aspect - to - string conversion . BuildList ( ) 15 % faster .
* - Added empty implementation of RefreshObjects ( ) to VirtualObjectListView since
* RefreshObjects ( ) cannot work on virtual lists .
* 2007 - 09 - 13 JPP - Corrected bug with custom sorter in VirtualObjectListView ( thanks for mpgjunky )
* 2007 - 09 - 07 JPP - Corrected image scaling bug in DrawAlignedImage ( ) ( thanks to krita970 )
* 2007 - 08 - 29 JPP - Allow item count labels on groups to be set per column ( thanks to cmarlow for idea )
* 2007 - 08 - 14 JPP - Major rework of DataListView based on Ian Griffiths ' s great work
* 2007 - 08 - 11 JPP - When empty , the control can now draw a "List Empty" m
* - Added GetColumn ( ) and GetItem ( ) methods
* v1 . 5
* 2007 - 08 - 03 JPP - Support animated GIFs in ImageRenderer
* - Allow height of rows to be specified - EXPERIMENTAL !
* 2007 - 07 - 26 JPP - Optimised redrawing of owner - drawn lists by remembering the update rect
* - Allow sort indicators to be turned off
* 2007 - 06 - 30 JPP - Added RowFormatter delegate
* - Allow a different label when there is only one item in a group ( thanks to cmarlow )
* v1 . 4
* 2007 - 04 - 12 JPP - Allow owner drawn on steriods !
* - Column headers now display sort indicators
* - ImageGetter delegates can now return ints , strings or Images
* ( Images are only visible if the list is owner drawn )
* - Added OLVColumn . MakeGroupies to help with group partitioning
* - All normal listview views are now supported
* - Allow dotted aspect names , e . g . Owner . Workgroup . Name ( thanks to OlafD )
* - Added SelectedObject and SelectedObjects properties
* v1 . 3
* 2007 - 03 - 01 JPP - Added DataListView
* - Added VirtualObjectListView
* - Added Freeze / Unfreeze capabilities
* - Allowed sort handler to be installed
* - Simplified sort comparisons : handles 95 % of cases with only 6 lines of code !
* - Fixed bug with alternative line colors on unsorted lists ( thanks to cmarlow )
* 2007 - 01 - 13 JPP - Fixed bug with lastSortOrder ( thanks to Kwan Fu Sit )
* - Non - OLVColumns are no longer allowed
* 2007 - 01 - 04 JPP - Clear sorter before rebuilding list . 10 x faster ! ( thanks to aaberg )
* - Include GetField in GetAspectByName ( ) so field values can be Invoked too .
* - Fixed subtle bug in RefreshItem ( ) that erased background colors .
* 2006 - 11 - 01 JPP - Added alternate line colouring
* 2006 - 10 - 20 JPP - Refactored all sorting comparisons and made it extendable . See ComparerManager .
* - Improved IDE integration
* - Made control DoubleBuffered
* - Added object selection methods
* 2006 - 10 - 13 JPP Implemented grouping and column sorting
* 2006 - 10 - 09 JPP Initial version
*
* TO DO :
* - Support undocumented group features : subseted groups , group footer items
*
* Copyright ( C ) 2006 - 2016 Phillip Piper
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*
* If you wish to use this code in a closed source application , please contact phillip . piper @gmail . com .
* /
using System ;
using System.Collections ;
using System.Collections.Generic ;
using System.ComponentModel ;
using System.Diagnostics ;
using System.Drawing ;
using System.Globalization ;
using System.IO ;
using System.Reflection ;
using System.Runtime.InteropServices ;
using System.Runtime.Serialization.Formatters.Binary ;
using System.Windows.Forms ;
using System.Windows.Forms.VisualStyles ;
using System.Runtime.Serialization.Formatters ;
using System.Threading ;
namespace BrightIdeasSoftware
{
/// <summary>
/// An ObjectListView is a much easier to use, and much more powerful, version of the ListView.
/// </summary>
/// <remarks>
/// <para>
/// An ObjectListView automatically populates a ListView control with information taken
/// from a given collection of objects. It can do this because each column is configured
/// to know which bit of the model object (the "aspect") it should be displaying. Columns similarly
/// understand how to sort the list based on their aspect, and how to construct groups
/// using their aspect.
/// </para>
/// <para>
/// Aspects are extracted by giving the name of a method to be called or a
/// property to be fetched. These names can be simple names or they can be dotted
/// to chain property access e.g. "Owner.Address.Postcode".
/// Aspects can also be extracted by installing a delegate.
/// </para>
/// <para>
/// An ObjectListView can show a "this list is empty" message when there is nothing to show in the list,
/// so that the user knows the control is supposed to be empty.
/// </para>
/// <para>
/// Right clicking on a column header should present a menu which can contain:
/// commands (sort, group, ungroup); filtering; and column selection. Whether these
/// parts of the menu appear is controlled by ShowCommandMenuOnRightClick,
/// ShowFilterMenuOnRightClick and SelectColumnsOnRightClick respectively.
/// </para>
/// <para>
/// The groups created by an ObjectListView can be configured to include other formatting
/// information, including a group icon, subtitle and task button. Using some undocumented
/// interfaces, these groups can even on virtual lists.
/// </para>
/// <para>
/// ObjectListView supports dragging rows to other places, including other application.
/// Special support is provide for drops from other ObjectListViews in the same application.
/// In many cases, an ObjectListView becomes a full drag source by setting <see cref="IsSimpleDragSource"/> to
/// true. Similarly, to accept drops, it is usually enough to set <see cref="IsSimpleDropSink"/> to true,
/// and then handle the <see cref="CanDrop"/> and <see cref="Dropped"/> events (or the <see cref="ModelCanDrop"/> and
/// <see cref="ModelDropped"/> events, if you only want to handle drops from other ObjectListViews in your application).
/// </para>
/// <para>
/// For these classes to build correctly, the project must have references to these assemblies:
/// </para>
/// <list type="bullet">
/// <item><description>System</description></item>
/// <item><description>System.Data</description></item>
/// <item><description>System.Design</description></item>
/// <item><description>System.Drawing</description></item>
/// <item><description>System.Windows.Forms (obviously)</description></item>
/// </list>
/// </remarks>
[Designer(typeof(BrightIdeasSoftware.Design.ObjectListViewDesigner))]
public partial class ObjectListView : ListView , ISupportInitialize {
#region Life and death
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> ObjectListView
/// </summary>
public ObjectListView ( ) {
this . ColumnClick + = new ColumnClickEventHandler ( this . HandleColumnClick ) ;
this . Layout + = new LayoutEventHandler ( this . HandleLayout ) ;
this . ColumnWidthChanging + = new ColumnWidthChangingEventHandler ( this . HandleColumnWidthChanging ) ;
this . ColumnWidthChanged + = new ColumnWidthChangedEventHandler ( this . HandleColumnWidthChanged ) ;
base . View = View . Details ;
2021-09-12 06:54:13 +00:00
base . FullRowSelect = true ;
2021-01-12 08:32:13 +00:00
// Turn on owner draw so that we are responsible for our own fates (and isolated from bugs in the underlying ListView)
this . OwnerDraw = true ;
// ReSharper disable DoNotCallOverridableMethodsInConstructor
this . DoubleBuffered = true ; // kill nasty flickers. hiss... me hates 'em
this . ShowSortIndicators = true ;
// Setup the overlays that will be controlled by the IDE settings
this . InitializeStandardOverlays ( ) ;
this . InitializeEmptyListMsgOverlay ( ) ;
// ReSharper restore DoNotCallOverridableMethodsInConstructor
}
/// <summary>
/// Dispose of any resources this instance has been using
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose ( bool disposing ) {
base . Dispose ( disposing ) ;
if ( ! disposing )
return ;
foreach ( GlassPanelForm glassPanel in this . glassPanels ) {
glassPanel . Unbind ( ) ;
glassPanel . Dispose ( ) ;
}
this . glassPanels . Clear ( ) ;
this . UnsubscribeNotifications ( null ) ;
}
#endregion
// TODO
//public CheckBoxSettings CheckBoxSettings {
// get { return checkBoxSettings; }
// private set { checkBoxSettings = value; }
//}
#region Static properties
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> ڴ<EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> ¡<EFBFBD>
/// </summary>
public static bool IsLeftMouseDown {
get { return ( Control . MouseButtons & MouseButtons . Left ) = = MouseButtons . Left ; }
}
/// <summary>
/// <20> <> ȡ<EFBFBD> ó<EFBFBD> <C3B3> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> Vista<74> <61> <EFBFBD> <EFBFBD> <EFBFBD> ߰汾<DFB0> <E6B1BE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
static public bool IsVistaOrLater {
get {
if ( ! ObjectListView . sIsVistaOrLater . HasValue )
ObjectListView . sIsVistaOrLater = Environment . OSVersion . Version . Major > = 6 ;
return ObjectListView . sIsVistaOrLater . Value ;
}
}
static private bool? sIsVistaOrLater ;
/// <summary>
/// <20> <> ȡ<EFBFBD> ó<EFBFBD> <C3B3> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> Win7<6E> <37> <EFBFBD> <EFBFBD> <EFBFBD> ߰汾<DFB0> <E6B1BE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
static public bool IsWin7OrLater {
get {
if ( ! ObjectListView . sIsWin7OrLater . HasValue ) {
// For some reason, Win7 is v6.1, not v7.0
Version version = Environment . OSVersion . Version ;
ObjectListView . sIsWin7OrLater = version . Major > 6 | | ( version . Major = = 6 & & version . Minor > 0 ) ;
}
return ObjectListView . sIsWin7OrLater . Value ;
}
}
static private bool? sIsWin7OrLater ;
/// <summary>
/// Gets or sets how what smoothing mode will be applied to graphic operations.
/// </summary>
static public System . Drawing . Drawing2D . SmoothingMode SmoothingMode {
get { return ObjectListView . sSmoothingMode ; }
set { ObjectListView . sSmoothingMode = value ; }
}
static private System . Drawing . Drawing2D . SmoothingMode sSmoothingMode =
System . Drawing . Drawing2D . SmoothingMode . HighQuality ;
/// <summary>
/// Gets or sets how should text be renderered.
/// </summary>
static public System . Drawing . Text . TextRenderingHint TextRenderingHint {
get { return ObjectListView . sTextRendereringHint ; }
set { ObjectListView . sTextRendereringHint = value ; }
}
static private System . Drawing . Text . TextRenderingHint sTextRendereringHint =
System . Drawing . Text . TextRenderingHint . SystemDefault ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> <EFBFBD> KeyΪNullʱ<6C> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> ڱ<EFBFBD> <DAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 乫<EFBFBD> <E4B9AB> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> Ա<EFBFBD> <D4B1> ػ<EFBFBD> <D8BB> <EFBFBD>
/// </summary>
static public string GroupTitleDefault {
get { return ObjectListView . sGroupTitleDefault ; }
set { ObjectListView . sGroupTitleDefault = value ? ? "{<7B> <EFBFBD> <DEB7> <EFBFBD> }" ; }
} static private string sGroupTitleDefault = "{<7B> <EFBFBD> <DEB7> <EFBFBD> }" ;
/// <summary>
/// Convert the given enumerable into an ArrayList as efficiently as possible
/// </summary>
/// <param name="collection">The source collection</param>
/// <param name="alwaysCreate">If true, this method will always create a new
/// collection.</param>
/// <returns>An ArrayList with the same contents as the given collection.</returns>
/// <remarks>
/// <para>When we move to .NET 3.5, we can use LINQ and not need this method.</para>
/// </remarks>
public static ArrayList EnumerableToArray ( IEnumerable collection , bool alwaysCreate ) {
if ( collection = = null )
return new ArrayList ( ) ;
if ( ! alwaysCreate ) {
ArrayList array = collection as ArrayList ;
if ( array ! = null )
return array ;
IList iList = collection as IList ;
if ( iList ! = null )
return ArrayList . Adapter ( iList ) ;
}
ICollection iCollection = collection as ICollection ;
if ( iCollection ! = null )
return new ArrayList ( iCollection ) ;
ArrayList newObjects = new ArrayList ( ) ;
foreach ( object x in collection )
newObjects . Add ( x ) ;
return newObjects ;
}
/// <summary>
/// Return the count of items in the given enumerable
/// </summary>
/// <param name="collection"></param>
/// <returns></returns>
/// <remarks>When we move to .NET 3.5, we can use LINQ and not need this method.</remarks>
public static int EnumerableCount ( IEnumerable collection ) {
if ( collection = = null )
return 0 ;
ICollection iCollection = collection as ICollection ;
if ( iCollection ! = null )
return iCollection . Count ;
int i = 0 ;
// ReSharper disable once UnusedVariable
foreach ( object x in collection )
i + + ;
return i ;
}
/// <summary>
/// Return whether or not the given enumerable is empty. A string is regarded as
/// an empty collection.
/// </summary>
/// <param name="collection"></param>
/// <returns>True if the given collection is null or empty</returns>
/// <remarks>
/// <para>When we move to .NET 3.5, we can use LINQ and not need this method.</para>
/// </remarks>
public static bool IsEnumerableEmpty ( IEnumerable collection ) {
return collection = = null | | ( collection is string ) | | ! collection . GetEnumerator ( ) . MoveNext ( ) ;
}
/// <summary>
/// Gets or sets whether all ObjectListViews will silently ignore missing aspect errors.
/// </summary>
/// <remarks>
/// <para>
/// By default, if an ObjectListView is asked to display an aspect
/// (i.e. a field/property/method)
/// that does not exist from a model, it displays an error message in that cell, since that
/// condition is normally a programming error. There are some use cases where
/// this is not an error -- in those cases, set this to true and ObjectListView will
/// simply display an empty cell.
/// </para>
/// <para>Be warned: if you set this to true, it can be very difficult to track down
/// typing mistakes or name changes in AspectNames.</para>
/// </remarks>
public static bool IgnoreMissingAspects {
get { return Munger . IgnoreMissingAspects ; }
set { Munger . IgnoreMissingAspects = value ; }
}
/// <summary>
/// Gets or sets whether the control will draw a rectangle in each cell showing the cell padding.
/// </summary>
/// <remarks>
/// <para>
/// This can help with debugging display problems from cell padding.
/// </para>
/// <para>As with all cell padding, this setting only takes effect when the control is owner drawn.</para>
/// </remarks>
public static bool ShowCellPaddingBounds {
get { return sShowCellPaddingBounds ; }
set { sShowCellPaddingBounds = value ; }
}
private static bool sShowCellPaddingBounds ;
/// <summary>
/// Gets the style that will be used by default to format disabled rows
/// </summary>
public static SimpleItemStyle DefaultDisabledItemStyle {
get {
if ( sDefaultDisabledItemStyle = = null ) {
sDefaultDisabledItemStyle = new SimpleItemStyle ( ) ;
sDefaultDisabledItemStyle . ForeColor = Color . DarkGray ;
}
return sDefaultDisabledItemStyle ;
}
}
private static SimpleItemStyle sDefaultDisabledItemStyle ;
/// <summary>
/// Gets the style that will be used by default to format hot rows
/// </summary>
public static HotItemStyle DefaultHotItemStyle {
get {
if ( sDefaultHotItemStyle = = null ) {
sDefaultHotItemStyle = new HotItemStyle ( ) ;
sDefaultHotItemStyle . BackColor = Color . FromArgb ( 224 , 235 , 253 ) ;
}
return sDefaultHotItemStyle ;
}
}
private static HotItemStyle sDefaultHotItemStyle ;
#endregion
#region Public properties
/// <summary>
/// Gets or sets an model filter that is combined with any column filtering that the end-user specifies.
/// </summary>
/// <remarks>This is different from the ModelFilter property, since setting that will replace
/// any column filtering, whereas setting this will combine this filter with the column filtering</remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual IModelFilter AdditionalFilter
{
get { return this . additionalFilter ; }
set
{
if ( this . additionalFilter = = value )
return ;
this . additionalFilter = value ;
this . UpdateColumnFiltering ( ) ;
}
}
private IModelFilter additionalFilter ;
/// <summary>
/// Get or set all the columns that this control knows about.
/// Only those columns where IsVisible is true will be seen by the user.
/// </summary>
/// <remarks>
/// <para>
/// If you want to add new columns programmatically, add them to
/// AllColumns and then call RebuildColumns(). Normally, you do not have to
/// deal with this property directly. Just use the IDE.
/// </para>
/// <para>If you do add or remove columns from the AllColumns collection,
/// you have to call RebuildColumns() to make those changes take effect.</para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Content ) ]
public virtual List < OLVColumn > AllColumns {
get { return this . allColumns ; }
set { this . allColumns = value ? ? new List < OLVColumn > ( ) ; }
}
private List < OLVColumn > allColumns = new List < OLVColumn > ( ) ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ÿ<EFBFBD> <C3BF> һ <EFBFBD> е ı <D0B5> <C4B1> <EFBFBD> ɫ
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> <EFBFBD> <EFBFBD> ɫ<EFBFBD> <C9AB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е ı <D0B5> <C4B1> <EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ʲô<CAB2> <C3B4> ɫ?" ) ,
DefaultValue ( typeof ( Color ) , "" ) ]
public Color AlternateRowBackColor {
get { return alternateRowBackColor ; }
set { alternateRowBackColor = value ; }
}
private Color alternateRowBackColor = Color . Empty ;
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õĽ<C3B5> <C4BD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ɫ<EFBFBD> <C9AB> Ĭ<EFBFBD> <C4AC> <EFBFBD> <EFBFBD> ɫ
/// </summary>
[Browsable(false)]
public virtual Color AlternateRowBackColorOrDefault {
get {
return this . alternateRowBackColor = = Color . Empty ? Color . LemonChiffon : this . alternateRowBackColor ;
}
}
/// <summary>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǿ<EFBFBD> <C7BF> ObjectListViewʼ <77> հ <EFBFBD> <D5B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> з<EFBFBD> <D0B7> 顣
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual OLVColumn AlwaysGroupByColumn {
get { return alwaysGroupByColumn ; }
set { alwaysGroupByColumn = value ; }
}
private OLVColumn alwaysGroupByColumn ;
/// <summary>
///<2F> <> <EFBFBD> <EFBFBD> AlwaysGroupByColumn<6D> <6E> Ϊ<EFBFBD> գ <EFBFBD> <D5A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Խ<EFBFBD> <D4BD> <EFBFBD> <EFBFBD> <EFBFBD> ȷ<EFBFBD> <C8B7> <EFBFBD> <EFBFBD> <EFBFBD> ζ<EFBFBD> <CEB6> <EFBFBD> Щ<EFBFBD> <D0A9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ե<EFBFBD> ֵΪSortOrder.None<6E> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ˳<EFBFBD> <EFBFBD> <F2BDABB8> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> ϴε<CFB4> <CEB5> <EFBFBD> <EFBFBD> ı <EFBFBD> <C4B1> <EFBFBD> <EFBFBD> л<EFBFBD> <D0BB> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual SortOrder AlwaysGroupBySortOrder {
get { return alwaysGroupBySortOrder ; }
set { alwaysGroupBySortOrder = value ; }
}
private SortOrder alwaysGroupBySortOrder = SortOrder . None ;
/// <summary>
/// Give access to the image list that is actually being used by the control
/// </summary>
/// <remarks>
/// Normally, it is preferable to use SmallImageList. Only use this property
/// if you know exactly what you are doing.
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual ImageList BaseSmallImageList {
get { return base . SmallImageList ; }
set { base . SmallImageList = value ; }
}
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ñ༭<C3B1> <E0BCAD> Ԫ<EFBFBD> <D4AA> <EFBFBD> ķ<EFBFBD> ʽ
/// </summary>
/// <remarks>Columns can also be marked as editable.</remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ñ༭<C3B1> <E0BCAD> Ԫ<EFBFBD> <D4AA> <EFBFBD> ķ<EFBFBD> ʽ " ) ,
DefaultValue ( CellEditActivateMode . None ) ]
public virtual CellEditActivateMode CellEditActivation {
get { return cellEditActivation ; }
set {
cellEditActivation = value ;
if ( this . Created )
this . Invalidate ( ) ;
}
}
private CellEditActivateMode cellEditActivation = CellEditActivateMode . None ;
/// <summary>
///<2F> ༭<EFBFBD> <E0BCAD> Ԫ<EFBFBD> <D4AA> ʱ<EFBFBD> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> (<28> <> ȥ<EFBFBD> <C8A5> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> ʹ <EFBFBD> õ<EFBFBD> <C3B5> κο ռ <CEBF> )<29> <>
/// Ĭ<> <C4AC> ֵΪ true.
/// </summary>
/// <remarks>
/// <para>This is always treated as true when the control is NOT owner drawn.</para>
/// <para>
/// When this is false and the control is owner drawn,
/// ObjectListView will try to calculate the width of the cell's
/// actual contents, and then size the editing control to be just the right width. If this is true,
/// the whole width of the cell will be used, regardless of the cell's contents.
/// </para>
/// <para>Each column can have a different value for property. This value from the control is only
/// used when a column is not specified one way or another.</para>
/// <para>Regardless of this setting, developers can specify the exact size of the editing control
/// by listening for the CellEditStarting event.</para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> ༭<EFBFBD> <E0BCAD> Ԫ<EFBFBD> <D4AA> ʱ<EFBFBD> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( true ) ]
public virtual bool CellEditUseWholeCell {
get { return cellEditUseWholeCell ; }
set { cellEditUseWholeCell = value ; }
}
private bool cellEditUseWholeCell ;
/// <summary>
/// Gets or sets the engine that will handle key presses during a cell edit operation.
/// Settings this to null will reset it to default value.
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public CellEditKeyEngine CellEditKeyEngine {
get { return this . cellEditKeyEngine ? ? ( this . cellEditKeyEngine = new CellEditKeyEngine ( ) ) ; }
set { this . cellEditKeyEngine = value ; }
}
private CellEditKeyEngine cellEditKeyEngine ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> ǰ<EFBFBD> <C7B0> <EFBFBD> ڱ༭<DAB1> <E0BCAD> Ԫ<EFBFBD> <D4AA> <EFBFBD> Ŀؼ<C4BF> <D8BC> <EFBFBD>
/// </summary>
/// <remarks>This will obviously be null if no cell is being edited.</remarks>
[Browsable(false)]
public Control CellEditor {
get {
return this . cellEditor ;
}
}
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ñ༭<C3B1> ؼ<EFBFBD> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> Ե<EFBFBD> <D4B5> <EFBFBD> ұ<EFBFBD> Ե<EFBFBD> ĵ<EFBFBD> Ԫ<EFBFBD> <D4AA> ʱTab<61> <62> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA>
///<2F> <> <EFBFBD> <EFBFBD> ΪFalse(Ĭ<> <C4AC> ֵ)<29> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Tab<61> <62> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ͬһ <CDAC> е <EFBFBD> <D0B5> <EFBFBD> һ <EFBFBD> ࡣ
///<2F> <> <EFBFBD> <EFBFBD> ΪTrue<75> <65> <EFBFBD> ༭<EFBFBD> <E0BCAD> <EFBFBD> ұߵ ĵ<DFB5> Ԫ<EFBFBD> <D4AA> ʱ<EFBFBD> <CAB1> Tab<61> <62> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> У <EFBFBD>
///<2F> ༭<EFBFBD> <E0BCAD> <EFBFBD> <EFBFBD> <EFBFBD> ߵ ĵ<DFB5> Ԫ<EFBFBD> <D4AA> ʱ<EFBFBD> <CAB1> Shift-Tab<61> <62> <EFBFBD> ϼ<EFBFBD> <CFBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> һ <EFBFBD> С <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> Ԫ<EFBFBD> <D4AA> <EFBFBD> ༭ʱ<E0BCAD> Ƿ<EFBFBD> Ӧʹ <D3A6> <CAB9> Tab/Shift-Tab<61> <62> <EFBFBD> ϼ<EFBFBD> <CFBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ? " ) ,
DefaultValue ( false ) ]
public virtual bool CellEditTabChangesRows {
get { return cellEditTabChangesRows ; }
set {
cellEditTabChangesRows = value ;
if ( cellEditTabChangesRows ) {
this . CellEditKeyEngine . SetKeyBehaviour ( Keys . Tab , CellEditCharacterBehaviour . ChangeColumnRight , CellEditAtEdgeBehaviour . ChangeRow ) ;
this . CellEditKeyEngine . SetKeyBehaviour ( Keys . Tab | Keys . Shift , CellEditCharacterBehaviour . ChangeColumnLeft , CellEditAtEdgeBehaviour . ChangeRow ) ;
} else {
this . CellEditKeyEngine . SetKeyBehaviour ( Keys . Tab , CellEditCharacterBehaviour . ChangeColumnRight , CellEditAtEdgeBehaviour . Wrap ) ;
this . CellEditKeyEngine . SetKeyBehaviour ( Keys . Tab | Keys . Shift , CellEditCharacterBehaviour . ChangeColumnLeft , CellEditAtEdgeBehaviour . Wrap ) ;
}
}
}
private bool cellEditTabChangesRows ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ñ༭<C3B1> <E0BCAD> Ԫ<EFBFBD> <D4AA> ʱEnter<65> <72> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA>
/// <20> <> <EFBFBD> <EFBFBD> ΪFalse(Ĭ<> <C4AC> ֵ)<29> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Enter<65> <72> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <F2B5A5B5> <EFBFBD> <EFBFBD> ɱ༭<C9B1> <E0BCAD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> ΪTrue<75> <65> <EFBFBD> <EFBFBD> Enter<65> <72> <EFBFBD> <EFBFBD> <EFBFBD> ɱ༭<C9B1> <E0BCAD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڵ<EFBFBD> ǰ<EFBFBD> <C7B0> Ԫ<EFBFBD> <D4AA> <EFBFBD> ·<EFBFBD> <C2B7> ĵ<EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> µı ༭<C4B1> <E0BCAD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ<EFBFBD> ڵײ<DAB5> <D7B2> <EFBFBD> Ԫ<EFBFBD> <D4AA> ʱ<EFBFBD> <CAB1> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> һ <EFBFBD> е Ķ<D0B5> <C4B6> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ñ༭<C3B1> <E0BCAD> Ԫ<EFBFBD> <D4AA> ʱEnter<65> <72> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ" ) ,
DefaultValue ( false ) ]
public virtual bool CellEditEnterChangesRows {
get { return cellEditEnterChangesRows ; }
set {
cellEditEnterChangesRows = value ;
if ( cellEditEnterChangesRows ) {
this . CellEditKeyEngine . SetKeyBehaviour ( Keys . Enter , CellEditCharacterBehaviour . ChangeRowDown , CellEditAtEdgeBehaviour . ChangeColumn ) ;
this . CellEditKeyEngine . SetKeyBehaviour ( Keys . Enter | Keys . Shift , CellEditCharacterBehaviour . ChangeRowUp , CellEditAtEdgeBehaviour . ChangeColumn ) ;
} else {
this . CellEditKeyEngine . SetKeyBehaviour ( Keys . Enter , CellEditCharacterBehaviour . EndEdit , CellEditAtEdgeBehaviour . EndEdit ) ;
this . CellEditKeyEngine . SetKeyBehaviour ( Keys . Enter | Keys . Shift , CellEditCharacterBehaviour . EndEdit , CellEditAtEdgeBehaviour . EndEdit ) ;
}
}
}
private bool cellEditEnterChangesRows ;
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> ʾ <EFBFBD> <CABE> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> ʾ <EFBFBD> Ĺ<EFBFBD> <C4B9> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> ؼ<EFBFBD>
/// </summary>
[Browsable(false)]
public ToolTipControl CellToolTip {
get {
if ( this . cellToolTip = = null ) {
this . CreateCellToolTip ( ) ;
}
return this . cellToolTip ;
}
}
private ToolTipControl cellToolTip ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ø<EFBFBD> <C3B8> <EFBFBD> <EFBFBD> <EFBFBD> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> Χ <EFBFBD> <CEA7> <EFBFBD> <EFBFBD> <EFBFBD> յ<EFBFBD> <D5B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڿ<EFBFBD> <DABF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 롣
/// </summary>
/// <remarks>
/// <para>Each value of the given rectangle will be treated as an inset from
/// the corresponding side. The width of the rectangle is the padding for the
/// right cell edge. The height of the rectangle is the padding for the bottom
/// cell edge.
/// </para>
/// <para>
/// So, this.olv1.CellPadding = new Rectangle(1, 2, 3, 4); will leave one pixel
/// of space to the left of the cell, 2 pixels at the top, 3 pixels of space
/// on the right edge, and 4 pixels of space at the bottom of each cell.
/// </para>
/// <para>
/// This setting only takes effect when the control is owner drawn.
/// </para>
/// <para>This setting only affects the contents of the cell. The background is
/// not affected.</para>
/// <para>If you set this to a foolish value, your control will appear to be empty.</para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ø<EFBFBD> <C3B8> <EFBFBD> <EFBFBD> <EFBFBD> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> Χ <EFBFBD> <CEA7> <EFBFBD> <EFBFBD> <EFBFBD> յ<EFBFBD> <D5B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڿ<EFBFBD> <DABF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 롣" ) ,
DefaultValue ( null ) ]
public Rectangle ? CellPadding {
get { return this . cellPadding ; }
set { this . cellPadding = value ; }
}
private Rectangle ? cellPadding ;
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> µ<EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> ֱ<EFBFBD> <D6B1> <EFBFBD> <EFBFBD> <EFBFBD> ķ<EFBFBD> ʽ <EFBFBD> <CABD>
/// </summary>
/// <remarks>This setting only takes effect when the control is owner drawn. It will only be noticable
/// when RowHeight has been set such that there is some vertical space in each row.</remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> µ<EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> ֱ<EFBFBD> <D6B1> <EFBFBD> <EFBFBD> <EFBFBD> ķ<EFBFBD> ʽ <EFBFBD> <CABD> " ) ,
DefaultValue ( StringAlignment . Center ) ]
public virtual StringAlignment CellVerticalAlignment {
get { return this . cellVerticalAlignment ; }
set { this . cellVerticalAlignment = value ; }
}
private StringAlignment cellVerticalAlignment = StringAlignment . Center ;
/// <summary>
/// Should this list show checkboxes?
/// </summary>
public new bool CheckBoxes {
get { return base . CheckBoxes ; }
set {
// Due to code in the base ListView class, turning off CheckBoxes on a virtual
// list always throws an InvalidOperationException. We have to do some major hacking
// to get around that
if ( this . VirtualMode ) {
// Leave virtual mode
this . StateImageList = null ;
this . VirtualListSize = 0 ;
this . VirtualMode = false ;
// Change the CheckBox setting while not in virtual mode
base . CheckBoxes = value ;
// Reinstate virtual mode
this . VirtualMode = true ;
// Re-enact the bits that we lost by switching to virtual mode
this . ShowGroups = this . ShowGroups ;
this . BuildList ( true ) ;
} else {
base . CheckBoxes = value ;
// Initialize the state image list so we can display indetermined values.
this . InitializeStateImageList ( ) ;
}
}
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> е <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> δѡ <CEB4> <D1A1> <EFBFBD> л<EFBFBD> ѡ <EFBFBD> ж<EFBFBD> <D0B6> У <EFBFBD> <D0A3> <EFBFBD> NULL
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual Object CheckedObject {
get {
IList checkedObjects = this . CheckedObjects ;
return checkedObjects . Count = = 1 ? checkedObjects [ 0 ] : null ;
}
set {
this . CheckedObjects = new ArrayList ( new Object [ ] { value } ) ;
}
}
/// <summary>
/// Get or set the collection of model objects that are checked.
/// When setting this property, any row whose model object isn't
/// in the given collection will be unchecked. Setting to null is
/// equivilent to unchecking all.
/// </summary>
/// <remarks>
/// <para>
/// This property returns a simple collection. Changes made to the returned
/// collection do NOT affect the list. This is different to the behaviour of
/// CheckedIndicies collection.
/// </para>
/// <para>
/// .NET's CheckedItems property is not helpful. It is just a short-hand for
/// iterating through the list looking for items that are checked.
/// </para>
/// <para>
/// The performance of the get method is O(n), where n is the number of items
/// in the control. The performance of the set method is
/// O(n + m) where m is the number of objects being checked. Be careful on long lists.
/// </para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual IList CheckedObjects {
get {
ArrayList list = new ArrayList ( ) ;
if ( this . CheckBoxes ) {
for ( int i = 0 ; i < this . GetItemCount ( ) ; i + + ) {
OLVListItem olvi = this . GetItem ( i ) ;
if ( olvi . CheckState = = CheckState . Checked )
list . Add ( olvi . RowObject ) ;
}
}
return list ;
}
set {
if ( ! this . CheckBoxes )
return ;
Stopwatch sw = Stopwatch . StartNew ( ) ;
// Set up an efficient way of testing for the presence of a particular model
Hashtable table = new Hashtable ( this . GetItemCount ( ) ) ;
if ( value ! = null ) {
foreach ( object x in value )
table [ x ] = true ;
}
this . BeginUpdate ( ) ;
foreach ( Object x in this . Objects ) {
this . SetObjectCheckedness ( x , table . ContainsKey ( x ) ? CheckState . Checked : CheckState . Unchecked ) ;
}
this . EndUpdate ( ) ;
Debug . WriteLine ( String . Format ( "PERF - Setting CheckedObjects on {2} objects took {0}ms / {1} ticks" , sw . ElapsedMilliseconds , sw . ElapsedTicks , this . GetItemCount ( ) ) ) ;
}
}
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ÿ<EFBFBD> ö<EFBFBD> ٶ<EFBFBD> <D9B6> <EFBFBD> <EFBFBD> е <EFBFBD> ѡ <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks>
/// Useful for checking all objects in the list.
/// </remarks>
/// <example>
/// this.olv1.CheckedObjectsEnumerable = this.olv1.Objects;
/// </example>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual IEnumerable CheckedObjectsEnumerable {
get {
return this . CheckedObjects ;
}
set {
this . CheckedObjects = ObjectListView . EnumerableToArray ( value , true ) ;
}
}
/// <summary>
/// Gets Columns for this list. We hide the original so we can associate
/// a specialised editor with it.
/// </summary>
[Editor("BrightIdeasSoftware.Design.OLVColumnCollectionEditor", "System.Drawing.Design.UITypeEditor")]
new public ListView . ColumnHeaderCollection Columns {
get {
return base . Columns ;
}
}
/// <summary>
///<2F> <> ȡ/<2F> <> <EFBFBD> õ<EFBFBD> <C3B5> б <EFBFBD> <D0B1> л<EFBFBD> <D0BB> <EFBFBD> TileView(ƽ <> <C6BD> <EFBFBD> <EFBFBD> ͼ)ʱӦʹ <D3A6> õ<EFBFBD> <C3B5> е <EFBFBD> <D0B5> б <EFBFBD> <D0B1> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
Obsolete ( "Use GetFilteredColumns() and OLVColumn.IsTileViewColumn instead" ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public List < OLVColumn > ColumnsForTileView {
get { return this . GetFilteredColumns ( View . Tile ) ; }
}
/// <summary>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> ʾ <EFBFBD> <CABE> ˳<EFBFBD> ؿɼ<D8BF> <C9BC> <EFBFBD>
/// </summary>
[Browsable(false)]
public virtual List < OLVColumn > ColumnsInDisplayOrder {
get {
OLVColumn [ ] columnsInDisplayOrder = new OLVColumn [ this . Columns . Count ] ;
foreach ( OLVColumn col in this . Columns ) {
columnsInDisplayOrder [ col . DisplayIndex ] = col ;
}
return new List < OLVColumn > ( columnsInDisplayOrder ) ;
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> ʾ <EFBFBD> б <EFBFBD> <D0B1> Ŀؼ<C4BF> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> ȥ<EFBFBD> κα <CEBA> <CEB1> <EFBFBD> <EFBFBD> ؼ<EFBFBD>
/// </summary>
[Browsable(false)]
public Rectangle ContentRectangle {
get {
Rectangle r = this . ClientRectangle ;
// If the listview has a header control, remove the header from the control area
if ( ( this . View = = View . Details | | this . ShowHeaderInAllViews ) & & this . HeaderControl ! = null ) {
Rectangle hdrBounds = new Rectangle ( ) ;
NativeMethods . GetClientRect ( this . HeaderControl . Handle , ref hdrBounds ) ;
r . Y = hdrBounds . Height ;
r . Height = r . Height - hdrBounds . Height ;
}
return r ;
}
}
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> û<EFBFBD> <C3BB> <EFBFBD> Ctrl+C<> <43> <EFBFBD> ϼ<EFBFBD> ʱ<EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ѡ <EFBFBD> <D1A1> <EFBFBD> и<EFBFBD> <D0B8> Ƶ<EFBFBD> <C6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> û<EFBFBD> <C3BB> <EFBFBD> Ctrl+C<> <43> <EFBFBD> ϼ<EFBFBD> ʱ<EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ѡ <EFBFBD> <D1A1> <EFBFBD> и<EFBFBD> <D0B8> Ƶ<EFBFBD> <C6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( true ) ]
public virtual bool CopySelectionOnControlC {
get { return copySelectionOnControlC ; }
set { copySelectionOnControlC = value ; }
}
private bool copySelectionOnControlC = true ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ð<EFBFBD> Ctrl+C<> <43> <EFBFBD> <EFBFBD> <EFBFBD> Ƶ<EFBFBD> <C6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 幦<EFBFBD> <E5B9A6> <EFBFBD> Ƿ<EFBFBD> Ӧʹ <D3A6> ð<EFBFBD> װ<EFBFBD> <D7B0> DragSource<63> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϵ<EFBFBD> <CFB5> <EFBFBD> <EFBFBD> ݶ<EFBFBD> <DDB6> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks>This is normally what is desired, unless a custom DragSource is installed
/// that does some very specialized drag-drop behaviour.</remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ð<EFBFBD> Ctrl + C<> <43> <EFBFBD> <EFBFBD> <EFBFBD> Ƶ<EFBFBD> <C6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 幦<EFBFBD> <E5B9A6> <EFBFBD> Ƿ<EFBFBD> Ӧʹ <D3A6> ð<EFBFBD> װ<EFBFBD> <D7B0> DragSource<63> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϵ<EFBFBD> <CFB5> <EFBFBD> <EFBFBD> ݶ<EFBFBD> <DDB6> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( true ) ]
public bool CopySelectionOnControlCUsesDragSource {
get { return this . copySelectionOnControlCUsesDragSource ; }
set { this . copySelectionOnControlCUsesDragSource = value ; }
}
private bool copySelectionOnControlCUsesDragSource = true ;
/// <summary>
/// Gets the list of decorations that will be drawn the ListView
/// </summary>
/// <remarks>
/// <para>
/// Do not modify the contents of this list directly. Use the AddDecoration() and RemoveDecoration() methods.
/// </para>
/// <para>
/// A decoration scrolls with the list contents. An overlay is fixed in place.
/// </para>
/// </remarks>
[Browsable(false)]
protected IList < IDecoration > Decorations {
get { return this . decorations ; }
}
private readonly List < IDecoration > decorations = new List < IDecoration > ( ) ;
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <DFBB> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ⱦ<EFBFBD> <C8BE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> δָ<CEB4> <D6B8> <EFBFBD> ض<EFBFBD> <D8B6> <EFBFBD> Ⱦ<EFBFBD> <C8BE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Խ<EFBFBD> <D4BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪNULL<4C> <4C> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ָ<EFBFBD> ΪHighlightTextRenende</remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public IRenderer DefaultRenderer {
get { return this . defaultRenderer ; }
set { this . defaultRenderer = value ? ? new HighlightTextRenderer ( ) ; }
}
private IRenderer defaultRenderer = new HighlightTextRenderer ( ) ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> ڻ<EFBFBD> <DABB> Ƹ<EFBFBD> <C6B8> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ⱦ<EFBFBD> <C8BE> <EFBFBD> <EFBFBD>
/// </summary>
/// <param name="model">The row model for the row</param>
/// <param name="column">The column to be drawn</param>
/// <returns>The renderer used for drawing a cell. Must not return null.</returns>
public IRenderer GetCellRenderer ( object model , OLVColumn column ) {
IRenderer renderer = this . CellRendererGetter = = null ? null : this . CellRendererGetter ( model , column ) ;
return renderer ? ? column . Renderer ? ? this . DefaultRenderer ;
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> ڽ<EFBFBD> <DABD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʽ <EFBFBD> <CABD>
/// </summary>
/// <remarks>If this is not set explicitly, <see cref="ObjectListView.DefaultDisabledItemStyle"/> will be used.</remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> ڽ<EFBFBD> <DABD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʽ <EFBFBD> <CABD> " ) ,
DefaultValue ( null ) ]
public SimpleItemStyle DisabledItemStyle
{
get { return disabledItemStyle ; }
set { disabledItemStyle = value ; }
}
private SimpleItemStyle disabledItemStyle ;
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѽ<EFBFBD> <D1BD> õ<EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <F2BCA4BB> ѽ<EFBFBD> <D1BD> õĶ<C3B5> <C4B6> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual IEnumerable DisabledObjects
{
get
{
return disabledObjects . Keys ;
}
set
{
this . disabledObjects . Clear ( ) ;
DisableObjects ( value ) ;
}
}
private readonly Hashtable disabledObjects = new Hashtable ( ) ;
/// <summary>
/// <20> жϴ˸ <CFB4> <CBB8> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> ѽ<EFBFBD> <D1BD> <EFBFBD>
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool IsDisabled ( object model )
{
return model ! = null & & this . disabledObjects . ContainsKey ( model ) ;
}
/// <summary>
/// <20> <> <EFBFBD> ø<EFBFBD> <C3B8> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <F3A1A3BD> õĶ<C3B5> <C4B6> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD>
/// </summary>
/// <param name="model">Must not be null</param>
public void DisableObject ( object model ) {
ArrayList list = new ArrayList ( ) ;
list . Add ( model ) ;
this . DisableObjects ( list ) ;
}
/// <summary>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> и<EFBFBD> <D0B8> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD>
/// </summary>
/// <param name="models"></param>
public void DisableObjects ( IEnumerable models )
{
if ( models = = null )
return ;
ArrayList list = ObjectListView . EnumerableToArray ( models , false ) ;
foreach ( object model in list )
{
if ( model = = null )
continue ;
this . disabledObjects [ model ] = true ;
int modelIndex = this . IndexOf ( model ) ;
if ( modelIndex > = 0 )
NativeMethods . DeselectOneItem ( this , modelIndex ) ;
}
this . RefreshObjects ( list ) ;
}
/// <summary>
///<2F> <> <EFBFBD> ø<EFBFBD> <C3B8> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ա<EFBFBD> <D4B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ٴ<EFBFBD> ѡ <EFBFBD> <EFBFBD> <F1B2A2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <param name="model">Must not be null</param>
public void EnableObject ( object model )
{
this . disabledObjects . Remove ( model ) ;
this . RefreshObject ( model ) ;
}
/// <summary>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> и<EFBFBD> <D0B8> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD>
/// </summary>
/// <param name="models"></param>
public void EnableObjects ( IEnumerable models )
{
if ( models = = null )
return ;
ArrayList list = ObjectListView . EnumerableToArray ( models , false ) ;
foreach ( object model in list )
{
if ( model ! = null )
this . disabledObjects . Remove ( model ) ;
}
this . RefreshObjects ( list ) ;
}
/// <summary>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> н<EFBFBD> <D0BD> õĶ<C3B5> <C4B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ⲻ<EFBFBD> ᴥ<EFBFBD> <E1B4A5> <EFBFBD> ػ<EFBFBD> <D8BB> <EFBFBD> <EFBFBD> ؽ<EFBFBD>
/// </summary>
protected void ClearDisabledObjects ( )
{
this . disabledObjects . Clear ( ) ;
}
/// <summary>
/// Gets or sets the object that controls how drags start from this control
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public IDragSource DragSource {
get { return this . dragSource ; }
set { this . dragSource = value ; }
}
private IDragSource dragSource ;
/// <summary>
/// Gets or sets the object that controls how drops are accepted and processed
/// by this ListView.
/// </summary>
/// <remarks>
/// <para>
/// If the given sink is an instance of SimpleDropSink, then events from the drop sink
/// will be automatically forwarded to the ObjectListView (which means that handlers
/// for those event can be configured within the IDE).
/// </para>
/// <para>If this is set to null, the control will not accept drops.</para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public IDropSink DropSink {
get { return this . dropSink ; }
set {
if ( this . dropSink = = value )
return ;
// Stop listening for events on the old sink
SimpleDropSink oldSink = this . dropSink as SimpleDropSink ;
if ( oldSink ! = null ) {
oldSink . CanDrop - = new EventHandler < OlvDropEventArgs > ( this . DropSinkCanDrop ) ;
oldSink . Dropped - = new EventHandler < OlvDropEventArgs > ( this . DropSinkDropped ) ;
oldSink . ModelCanDrop - = new EventHandler < ModelDropEventArgs > ( this . DropSinkModelCanDrop ) ;
oldSink . ModelDropped - = new EventHandler < ModelDropEventArgs > ( this . DropSinkModelDropped ) ;
}
this . dropSink = value ;
this . AllowDrop = ( value ! = null ) ;
if ( this . dropSink ! = null )
this . dropSink . ListView = this ;
// Start listening for events on the new sink
SimpleDropSink newSink = value as SimpleDropSink ;
if ( newSink ! = null ) {
newSink . CanDrop + = new EventHandler < OlvDropEventArgs > ( this . DropSinkCanDrop ) ;
newSink . Dropped + = new EventHandler < OlvDropEventArgs > ( this . DropSinkDropped ) ;
newSink . ModelCanDrop + = new EventHandler < ModelDropEventArgs > ( this . DropSinkModelCanDrop ) ;
newSink . ModelDropped + = new EventHandler < ModelDropEventArgs > ( this . DropSinkModelDropped ) ;
}
}
}
private IDropSink dropSink ;
// Forward events from the drop sink to the control itself
void DropSinkCanDrop ( object sender , OlvDropEventArgs e ) { this . OnCanDrop ( e ) ; }
void DropSinkDropped ( object sender , OlvDropEventArgs e ) { this . OnDropped ( e ) ; }
void DropSinkModelCanDrop ( object sender , ModelDropEventArgs e ) { this . OnModelCanDrop ( e ) ; }
void DropSinkModelDropped ( object sender , ModelDropEventArgs e ) { this . OnModelDropped ( e ) ; }
/// <summary>
/// This registry decides what control should be used to edit what cells, based
/// on the type of the value in the cell.
/// </summary>
/// <see cref="EditorRegistry"/>
/// <remarks>All instances of ObjectListView share the same editor registry.</remarks>
// ReSharper disable FieldCanBeMadeReadOnly.Global
static public EditorRegistry EditorRegistry = new EditorRegistry ( ) ;
// ReSharper restore FieldCanBeMadeReadOnly.Global
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڴ<EFBFBD> <DAB4> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> ʱӦ<CAB1> <D3A6> ʾ <EFBFBD> <CABE> <EFBFBD> ı <EFBFBD> <C4B1> <EFBFBD>
/// </summary>
/// <remarks>If the EmptyListMsgOverlay has been changed to something other than a TextOverlay,
/// this property does nothing</remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> б <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> ڿؼ<DABF> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> Ϣ" ) ,
DefaultValue ( null ) ,
Localizable ( true ) ]
public virtual String EmptyListMsg {
get {
TextOverlay overlay = this . EmptyListMsgOverlay as TextOverlay ;
return overlay = = null ? null : overlay . Text ;
}
set {
TextOverlay overlay = this . EmptyListMsgOverlay as TextOverlay ;
if ( overlay ! = null ) {
overlay . Text = value ;
this . Invalidate ( ) ;
}
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> ϢʱӦʹ <D3A6> õ<EFBFBD> <C3B5> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks>If the EmptyListMsgOverlay has been changed to something other than a TextOverlay,
/// this property does nothing</remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> ϢʱӦʹ <D3A6> õ<EFBFBD> <C3B5> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( null ) ]
public virtual Font EmptyListMsgFont {
get {
TextOverlay overlay = this . EmptyListMsgOverlay as TextOverlay ;
return overlay = = null ? null : overlay . Font ;
}
set {
TextOverlay overlay = this . EmptyListMsgOverlay as TextOverlay ;
if ( overlay ! = null )
overlay . Font = value ;
}
}
/// <summary>
/// <20> <> <EFBFBD> ء<EFBFBD> <D8A1> б <EFBFBD> Ϊ<EFBFBD> ա <EFBFBD> <D5A1> <EFBFBD> Ϣ<EFBFBD> <CFA2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> ֵ
/// </summary>
[Browsable(false)]
public virtual Font EmptyListMsgFontOrDefault {
get {
return this . EmptyListMsgFont ? ? new Font ( "Tahoma" , 14 ) ;
}
}
/// <summary>
/// Gets or sets the overlay responsible for drawing the List Empty msg.
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual IOverlay EmptyListMsgOverlay {
get { return this . emptyListMsgOverlay ; }
set {
if ( this . emptyListMsgOverlay ! = value ) {
this . emptyListMsgOverlay = value ;
this . Invalidate ( ) ;
}
}
}
private IOverlay emptyListMsgOverlay ;
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> ɸѡ <C9B8> <D1A1> <EFBFBD> Ҵ<EFBFBD> <D2B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ķ<EFBFBD> <C4B6> <EFBFBD> <EFBFBD> ļ<EFBFBD> <C4BC> ϡ<EFBFBD>
/// </summary>
/// <remarks>
/// <para>
/// This collection is the result of filtering the current list of objects.
/// It is not a snapshot of the filtered list that was last used to build the control.
/// </para>
/// <para>
/// Normal warnings apply when using this with virtual lists. It will work, but it
/// may take a while.
/// </para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
virtual public IEnumerable FilteredObjects {
get {
if ( this . UseFiltering )
return this . FilterObjects ( this . Objects , this . ModelFilter , this . ListFilter ) ;
return this . Objects ;
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1> <EFBFBD> ˵<EFBFBD> <CBB5> IJ<EFBFBD> <C4B2> Զ<EFBFBD> <D4B6> <EFBFBD>
/// </summary>
/// <remarks><3E> <> <EFBFBD> <EFBFBD> ΪNULL<4C> <4C> <EFBFBD> <EFBFBD> <F2B2BBBB> <EFBFBD> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1> <EFBFBD> ˵<EFBFBD> <CBB5> <EFBFBD> </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public FilterMenuBuilder FilterMenuBuildStrategy {
get { return filterMenuBuilder ; }
set { filterMenuBuilder = value ; }
}
private FilterMenuBuilder filterMenuBuilder = new FilterMenuBuilder ( ) ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> þ<EFBFBD> <C3BE> м<EFBFBD> <D0BC> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks>
/// <para>
/// Setting an object to be focused does *not* select it. If you want to select and focus a row,
/// use <see cref="SelectedObject"/>.
/// </para>
/// <para>
/// This property is not generally used and is only useful in specialized situations.
/// </para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual Object FocusedObject {
get { return this . FocusedItem = = null ? null : ( ( OLVListItem ) this . FocusedItem ) . RowObject ; }
set {
OLVListItem item = this . ModelToItem ( value ) ;
if ( item ! = null )
item . Focused = true ;
}
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> Groups<70> <73> <EFBFBD> ϣ<EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> ڡ<EFBFBD> <DAA1> <EFBFBD> <EFBFBD> ԡ<EFBFBD> <D4A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> в<EFBFBD> <D0B2> ɼ<EFBFBD> <C9BC> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
new public ListViewGroupCollection Groups {
get { return base . Groups ; }
}
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ÷<EFBFBD> <C3B7> <EFBFBD> ʹ <EFBFBD> õ<EFBFBD> ImageList
/// </summary>
/// <remarks><3E> <> <EFBFBD> <EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD> ô<EFBFBD> ѡ <EFBFBD> <EFBFBD> <EEA3AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ⽫<EFBFBD> <E2BDAB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> κ<EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ÷<EFBFBD> <C3B7> <EFBFBD> ʹ <EFBFBD> õ<EFBFBD> ImageList" ) ,
DefaultValue ( null ) ]
public ImageList GroupImageList {
get { return this . groupImageList ; }
set {
this . groupImageList = value ;
if ( this . Created ) {
NativeMethods . SetGroupImageList ( this , value ) ;
}
}
}
private ImageList groupImageList ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> ջ<EFBFBD> <D5BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĿʱӦ<CAB1> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǩ<EFBFBD> ĸ<EFBFBD> ʽ
/// </summary>
/// <remarks>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ĸ<EFBFBD> ʽ <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ռ λ<D5BC> <CEBB> <EFBFBD> <EFBFBD>
/// <list type="bullet">
/// <item><description>{0} - ԭ<> <D4AD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> </description></item>
/// <item><description>{1} - <20> <> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> Ŀ<EFBFBD> <C4BF> </description></item>
/// </list>
/// </remarks>
/// <example>"[{0} [{1} <20> <> ]"</example>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> ջ<EFBFBD> <D5BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĿʱӦ<CAB1> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǩ<EFBFBD> ĸ<EFBFBD> ʽ " ) ,
DefaultValue ( null ) ,
Localizable ( true ) ]
public virtual string GroupWithItemCountFormat {
get { return groupWithItemCountFormat ; }
set { groupWithItemCountFormat = value ; }
}
private string groupWithItemCountFormat ;
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> this.GroupWithItemCountFormat<61> <74> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> ֵ
/// </summary>
[Browsable(false)]
public virtual string GroupWithItemCountFormatOrDefault {
get {
return String . IsNullOrEmpty ( this . GroupWithItemCountFormat ) ? "{0} [{1} <20> <> ]" : this . GroupWithItemCountFormat ;
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĿʱӦ<CAB1> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǩ<EFBFBD> ĸ<EFBFBD> ʽ
/// </summary>
/// <remarks>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ĸ<EFBFBD> ʽ <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ռ λ<D5BC> <CEBB> <EFBFBD> <EFBFBD>
/// <list type="bullet">
/// <item><description>{0} - ԭ<> <D4AD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> </description></item>
/// <item><description>{1} - <20> <> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> Ŀ<EFBFBD> <C4BF> (<28> <> <EFBFBD> <EFBFBD> 1)</description></item>
/// </list>
/// </remarks>
/// <example>"[{0} [{1} <20> <> ]"</example>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĿʱӦ<CAB1> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǩ<EFBFBD> ĸ<EFBFBD> ʽ " ) ,
DefaultValue ( null ) ,
Localizable ( true ) ]
public virtual string GroupWithItemCountSingularFormat {
get { return groupWithItemCountSingularFormat ; }
set { groupWithItemCountSingularFormat = value ; }
}
private string groupWithItemCountSingularFormat ;
/// <summary>
/// <20> <> ȡGroupWithItemCountSingularFormat<61> <74> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> ֵ
/// </summary>
[Browsable(false)]
public virtual string GroupWithItemCountSingularFormatOrDefault {
get {
return String . IsNullOrEmpty ( this . GroupWithItemCountSingularFormat ) ? "{0} [{1} <20> <> ]" : this . GroupWithItemCountSingularFormat ;
}
}
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ô<EFBFBD> ObjectListView<65> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> ۵ <EFBFBD> <DBB5> <EFBFBD>
/// </summary>
/// <remarks>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֻ֧<D6BB> <D6A7> Vista<74> <61> ֮<EFBFBD> <D6AE> <EFBFBD> <EFBFBD> ϵͳ.
/// </remarks>
[ Browsable ( true ) ,
Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ô<EFBFBD> ObjectListView<65> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> ۵ <EFBFBD> (Vista<74> <61> ֮<EFBFBD> <D6AE> <EFBFBD> <EFBFBD> ϵͳ<CFB5> <CDB3> ֧<EFBFBD> <D6A7> )." ) ,
DefaultValue ( true ) ]
public bool HasCollapsibleGroups {
get { return hasCollapsibleGroups ; }
set { hasCollapsibleGroups = value ; }
}
private bool hasCollapsibleGroups = true ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> ǰ<EFBFBD> б <EFBFBD> <D0B1> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> ڵ<EFBFBD> <DAB5> б <EFBFBD> Ϊ<EFBFBD> <CEAA> ʱ<EFBFBD> <CAB1> ʾ <EFBFBD> <CABE> <EFBFBD> ı <EFBFBD>
/// </summary>
[Browsable(false)]
public virtual bool HasEmptyListMsg {
get { return ! String . IsNullOrEmpty ( this . EmptyListMsg ) ; }
}
/// <summary>
/// <20> <> ȡ<EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> Ƶĵ<C6B5> <C4B5> Ӳ<EFBFBD>
/// </summary>
[Browsable(false)]
public bool HasOverlays {
get {
return ( this . Overlays . Count > 2 | |
this . imageOverlay . Image ! = null | |
! String . IsNullOrEmpty ( this . textOverlay . Text ) ) ;
}
}
/// <summary>
/// <20> <> ȡListView<65> <77> <EFBFBD> <EFBFBD> ͷ<EFBFBD> ؼ<EFBFBD>
/// </summary>
[Browsable(false)]
public HeaderControl HeaderControl {
get { return this . headerControl ? ? ( this . headerControl = new HeaderControl ( this ) ) ; }
}
private HeaderControl headerControl ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> ı <EFBFBD> <C4B1> Ļ<EFBFBD> <C4BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> п<EFBFBD> <D0BF> <EFBFBD> ͨ<EFBFBD> <CDA8> <EFBFBD> <EFBFBD> HeaderFormatStyle<6C> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> д<EFBFBD> <D0B4> <EFBFBD> <EFBFBD> <EFBFBD> á<EFBFBD> </remarks>
[DefaultValue(null)]
[Browsable(false)]
[Obsolete("<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> HeaderFormatStyle", false)]
public Font HeaderFont {
get { return this . HeaderFormatStyle = = null ? null : this . HeaderFormatStyle . Normal . Font ; }
set {
if ( value = = null & & this . HeaderFormatStyle = = null )
return ;
if ( this . HeaderFormatStyle = = null )
this . HeaderFormatStyle = new HeaderFormatStyle ( ) ;
this . HeaderFormatStyle . SetFont ( value ) ;
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> <EFBFBD> ڻ<EFBFBD> <DABB> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʽ
/// </summary>
/// <remarks>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> HeaderUsesThemesΪfalseʱ<65> <CAB1> ʹ <EFBFBD> ô<EFBFBD> ѡ <EFBFBD>
/// </para>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> п<EFBFBD> <D0BF> <EFBFBD> ͨ<EFBFBD> <CDA8> <EFBFBD> <EFBFBD> HeaderFormatStyle<6C> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> д<EFBFBD> <D0B4> <EFBFBD> <EFBFBD> <EFBFBD> á<EFBFBD>
/// </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> <EFBFBD> ڻ<EFBFBD> <DABB> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʽ " ) ,
DefaultValue ( null ) ]
public HeaderFormatStyle HeaderFormatStyle {
get { return this . headerFormatStyle ; }
set { this . headerFormatStyle = value ; }
}
private HeaderFormatStyle headerFormatStyle ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ñ<EFBFBD> <C3B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ȡ<DFB6> -1<> <31> ʾ û<CABE> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ñ<EFBFBD> <C3B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ȡ<DFB6> -1<> <31> ʾ û<CABE> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> " ) ,
DefaultValue ( - 1 ) ]
public int HeaderMaximumHeight
{
get { return headerMaximumHeight ; }
set { headerMaximumHeight = value ; }
}
private int headerMaximumHeight = - 1 ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ñ<EFBFBD> <C3B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> ߶ȡ<DFB6> -1<> <31> ʾ û<CABE> <C3BB> <EFBFBD> <EFBFBD> С ֵ<D0A1> <D6B5>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ñ<EFBFBD> <C3B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> ߶ȡ<DFB6> -1<> <31> ʾ û<CABE> <C3BB> <EFBFBD> <EFBFBD> С ֵ<D0A1> <D6B5> " ) ,
DefaultValue ( - 1 ) ]
public int HeaderMinimumHeight
{
get { return headerMinimumHeight ; }
set { headerMinimumHeight = value ; }
}
private int headerMinimumHeight = - 1 ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> ϸ<EFBFBD> <CFB8> <EFBFBD> <EFBFBD> ղ<EFBFBD> <D5B2> <EFBFBD> ϵͳ<CFB5> <CDB3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʊ<EFBFBD> <C6B1> ⡣
/// </summary>
/// <remarks>
/// <para>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊtrue<75> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͷ<EFBFBD> <CDB7> <EFBFBD> <EFBFBD> ȫ<EFBFBD> <C8AB> ϵͳ<CFB5> <CDB3> <EFBFBD> ֣<EFBFBD> <D6A3> <EFBFBD> <EFBFBD> <EFBFBD> ҪObjectListViews<77> <73> <EFBFBD> κ<EFBFBD> <CEBA> <EFBFBD> <EFBFBD> <EFBFBD> <E2B4A6> <EFBFBD> <EFBFBD>
///ҳü<D2B3> н<EFBFBD> û<EFBFBD> <C3BB> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> û<EFBFBD> й<EFBFBD> <D0B9> <EFBFBD> <EFBFBD> <EFBFBD> ָʾ <D6B8> <CABE> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> ֻ<EFBFBD> <D6BB> С <EFBFBD> û<EFBFBD> <C3BB> ҳü<D2B3> <C3BC> ʽ <EFBFBD> <CABD> û<EFBFBD> и<EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD>
/// </para>
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪFalse<73> <65> ObjectListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> õķ<C3B5> ʽ <EFBFBD> <CABD> <EFBFBD> ֱ<EFBFBD> <D6B1> ⡣
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> ܣ<EFBFBD> <DCA3> <EFBFBD> ObjectListView<65> Ὣ<EFBFBD> <E1BDAB> Ⱦί<C8BE> и<EFBFBD> <D0B8> <EFBFBD> <EFBFBD> <EFBFBD> ϵͳ<CFB5> <CDB3>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ObjectListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> Ʊ<EFBFBD> <C6B1> ⡣
/// </para>
/// <para>
/// û<> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ч<EFBFBD> <D0A7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϵͳ<CFB5> <CDB3> ͬ<EFBFBD> <CDAC> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC> <EFBFBD> <EFBFBD> <EFBFBD> ٣<EFBFBD> <D9A3> <EFBFBD> <EFBFBD> <EFBFBD> ָʾ <D6B8> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> DZ<EFBFBD> <EFBFBD> ġ<EFBFBD>
/// </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> ϸ<EFBFBD> <CFB8> <EFBFBD> <EFBFBD> ղ<EFBFBD> <D5B2> <EFBFBD> ϵͳ<CFB5> <CDB3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʊ<EFBFBD> <C6B1> <EFBFBD> " ) ,
DefaultValue ( false ) ]
public bool HeaderUsesThemes {
get { return this . headerUsesThemes ; }
set { this . headerUsesThemes = value ; }
}
private bool headerUsesThemes ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͷ<EFBFBD> <CDB7> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> ı <EFBFBD> <C4B1> Ƿ<EFBFBD> <C7B7> Զ<EFBFBD> <D4B6> <EFBFBD> <EFBFBD> С <EFBFBD>
/// </summary>
/// <remarks>
/// <para><3E> <> <EFBFBD> ڵ<EFBFBD> <DAB5> <EFBFBD> ֮<EFBFBD> <D6AE> Ӧ<EFBFBD> û<EFBFBD> <C3BB> з<EFBFBD> <D0B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĵ<EFBFBD> <C4B5> <EFBFBD> <EFBFBD> Խ<EFBFBD> <D4BD> <EFBFBD> ʡ<EFBFBD> ԡ<EFBFBD> </para>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> ͷ<EFBFBD> <CDB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> HeaderUsesThemes<65> <73> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊfalse<73> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϵͳ<CFB5> <CDB3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͷ<EFBFBD> <CDB7> <EFBFBD> <EFBFBD> <EFBFBD> Ҳ<EFBFBD> <D2B2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Զ<EFBFBD> <D4B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> <C4B1> <EFBFBD>
/// </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
2021-01-23 15:35:30 +00:00
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͷ<EFBFBD> <CDB7> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> ı <EFBFBD> <C4B1> Ƿ<EFBFBD> <C7B7> Զ<EFBFBD> <D4B6> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
2021-01-12 08:32:13 +00:00
DefaultValue ( false ) ]
public bool HeaderWordWrap {
get { return this . headerWordWrap ; }
set {
this . headerWordWrap = value ;
if ( this . headerControl ! = null )
this . headerControl . WordWrap = value ;
}
}
private bool headerWordWrap ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> ʾ <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> Ĺ<EFBFBD> <C4B9> <EFBFBD> <EFBFBD> <EFBFBD> ʾ
/// </summary>
[Browsable(false)]
public ToolTipControl HeaderToolTip {
get {
return this . HeaderControl . ToolTip ;
}
}
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> 굱ǰ<EAB5B1> <C7B0> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual int HotRowIndex {
get { return this . hotRowIndex ; }
protected set { this . hotRowIndex = value ; }
}
private int hotRowIndex ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> 굱ǰ<EAB5B1> <C7B0> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual int HotColumnIndex {
get { return this . hotColumnIndex ; }
protected set { this . hotColumnIndex = value ; }
}
private int hotColumnIndex ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> 굱ǰ<EAB5B1> <C7B0> <EFBFBD> ڵ<EFBFBD> <DAB5> <EFBFBD> /<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual HitTestLocation HotCellHitLocation {
get { return this . hotCellHitLocation ; }
protected set { this . hotCellHitLocation = value ; }
}
private HitTestLocation hotCellHitLocation ;
/// <summary>
/// Gets an extended indication of the part of item/subitem/group that the mouse is currently over
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual HitTestLocationEx HotCellHitLocationEx
{
get { return this . hotCellHitLocationEx ; }
protected set { this . hotCellHitLocationEx = value ; }
}
private HitTestLocationEx hotCellHitLocationEx ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڵ<EFBFBD> <DAB5> 顣
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public OLVGroup HotGroup
{
get { return hotGroup ; }
internal set { hotGroup = value ; }
}
private OLVGroup hotGroup ;
/// <summary>
///<2F> <> <EFBFBD> ڡ<EFBFBD> <DAA1> ȡ<EFBFBD> ״̬<D7B4> <CCAC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڹ<EFBFBD> <DAB9> <EFBFBD> <EFBFBD> ·<EFBFBD> <C2B7> <EFBFBD> -1<> <31> ʾ û<CABE> <C3BB> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF>
/// </summary>
[ Browsable ( false ) ,
Obsolete ( "<22> <> ʹ <EFBFBD> <CAB9> HotRowIndex <20> <> <EFBFBD> <EFBFBD> " , false ) ]
public virtual int HotItemIndex {
get { return this . HotRowIndex ; }
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ö<EFBFBD> <C3B6> α <EFBFBD> <CEB1> µ<EFBFBD> <C2B5> <EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> ָ<EFBFBD> ʽ
/// </summary>
/// <remarks>
/// <para>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> UseHotItemΪtrueʱ<65> <CAB1> Ч<EFBFBD> <D0A7>
/// </para>
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʽ <EFBFBD> <CABD> <EFBFBD> е <EFBFBD> <D0B5> Ӳ㣬<D3B2> <E3A3AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> á<EFBFBD> *֮ǰ* <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ԡ<EFBFBD> ֮<EFBFBD> <D6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ԡ<EFBFBD> </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ö<EFBFBD> <C3B6> α <EFBFBD> <CEB1> µ<EFBFBD> <C2B5> <EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> ָ<EFBFBD> ʽ " ) ,
DefaultValue ( null ) ]
public virtual HotItemStyle HotItemStyle {
get { return this . hotItemStyle ; }
set {
if ( this . HotItemStyle ! = null )
this . RemoveOverlay ( this . HotItemStyle . Overlay ) ;
this . hotItemStyle = value ;
if ( this . HotItemStyle ! = null )
this . AddOverlay ( this . HotItemStyle . Overlay ) ;
}
}
private HotItemStyle hotItemStyle ;
/// <summary>
/// <20> <> ȡ<EFBFBD> Ѱ<EFBFBD> װ<EFBFBD> <D7B0> <EFBFBD> ȵ<EFBFBD> <C8B5> <EFBFBD> <EFBFBD> <EFBFBD> ʽ <EFBFBD> <CABD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> ֵ<EFBFBD> <D6B5>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual HotItemStyle HotItemStyleOrDefault {
get { return this . HotItemStyle ? ? ObjectListView . DefaultHotItemStyle ; }
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> ָ<EFBFBD> ʽ Ӧ<CABD> <D3A6> <EFBFBD> ڳ<EFBFBD> <DAB3> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> ָ<EFBFBD> ʽ Ӧ<CABD> <D3A6> <EFBFBD> ڳ<EFBFBD> <DAB3> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( null ) ]
public virtual HyperlinkStyle HyperlinkStyle {
get { return this . hyperlinkStyle ; }
set { this . hyperlinkStyle = value ; }
}
private HyperlinkStyle hyperlinkStyle ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> е ı <D0B5> <C4B1> <EFBFBD> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> ʲô<CAB2> <C3B4> ɫ
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> е ı <D0B5> <C4B1> <EFBFBD> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> ʲô<CAB2> <C3B4> ɫ" ) ,
DefaultValue ( typeof ( Color ) , "" ) ]
public virtual Color SelectedBackColor {
get { return this . selectedBackColor ; }
set { this . selectedBackColor = value ; }
}
private Color selectedBackColor = Color . Empty ;
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> е ı <D0B5> <C4B1> <EFBFBD> <EFBFBD> <EFBFBD> ɫ<EFBFBD> <C9AB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> ֵ
/// </summary>
[Browsable(false)]
public virtual Color SelectedBackColorOrDefault {
get {
return this . SelectedBackColor . IsEmpty ? SystemColors . Highlight : this . SelectedBackColor ;
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> ʲô<CAB2> <C3B4> ɫ
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> ʲô<CAB2> <C3B4> ɫ" ) ,
DefaultValue ( typeof ( Color ) , "" ) ]
public virtual Color SelectedForeColor {
get { return this . selectedForeColor ; }
set { this . selectedForeColor = value ; }
}
private Color selectedForeColor = Color . Empty ;
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɫ<EFBFBD> <C9AB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> ֵ
/// </summary>
[Browsable(false)]
public virtual Color SelectedForeColorOrDefault {
get {
return this . SelectedForeColor . IsEmpty ? SystemColors . HighlightText : this . SelectedForeColor ;
}
}
/// <summary>
/// ʹ <> <CAB9> SelectedBackColor <20> <> <EFBFBD> <EFBFBD>
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Obsolete("ʹ <> <CAB9> SelectedBackColor <20> <> <EFBFBD> <EFBFBD> ")]
public virtual Color HighlightBackgroundColor { get { return this . SelectedBackColor ; } set { this . SelectedBackColor = value ; } }
/// <summary>
/// ʹ <> <CAB9> SelectedBackColorOrDefault <20> <> <EFBFBD> <EFBFBD>
/// </summary>
2021-01-23 15:35:30 +00:00
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
2021-01-12 08:32:13 +00:00
[Obsolete("ʹ <> <CAB9> SelectedBackColorOrDefault <20> <> <EFBFBD> <EFBFBD> ")]
public virtual Color HighlightBackgroundColorOrDefault { get { return this . SelectedBackColorOrDefault ; } }
/// <summary>
/// ʹ <> <CAB9> SelectedForeColor <20> <> <EFBFBD> <EFBFBD>
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Obsolete("ʹ <> <CAB9> SelectedForeColor <20> <> <EFBFBD> <EFBFBD> ")]
public virtual Color HighlightForegroundColor { get { return this . SelectedForeColor ; } set { this . SelectedForeColor = value ; } }
/// <summary>
/// ʹ <> <CAB9> SelectedForeColorOrDefault <20> <> <EFBFBD> <EFBFBD>
/// </summary>
2021-01-23 15:35:30 +00:00
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
2021-01-12 08:32:13 +00:00
[Obsolete("ʹ <> <CAB9> SelectedForeColorOrDefault <20> <> <EFBFBD> <EFBFBD> ")]
public virtual Color HighlightForegroundColorOrDefault { get { return this . SelectedForeColorOrDefault ; } }
/// <summary>
/// ʹ <> <CAB9> UnfocusedSelectedBackColor <20> <> <EFBFBD> <EFBFBD>
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Obsolete("ʹ <> <CAB9> UnfocusedSelectedBackColor <20> <> <EFBFBD> <EFBFBD> ")]
public virtual Color UnfocusedHighlightBackgroundColor { get { return this . UnfocusedSelectedBackColor ; } set { this . UnfocusedSelectedBackColor = value ; } }
/// <summary>
/// ʹ <> <CAB9> UnfocusedSelectedBackColorOrDefault <20> <> <EFBFBD> <EFBFBD>
/// </summary>
[Obsolete("ʹ <> <CAB9> UnfocusedSelectedBackColorOrDefault <20> <> <EFBFBD> <EFBFBD> ")]
public virtual Color UnfocusedHighlightBackgroundColorOrDefault { get { return this . UnfocusedSelectedBackColorOrDefault ; } }
/// <summary>
/// ʹ <> <CAB9> UnfocusedSelectedForeColor <20> <> <EFBFBD> <EFBFBD>
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Obsolete("ʹ <> <CAB9> UnfocusedSelectedForeColor <20> <> <EFBFBD> <EFBFBD> ")]
public virtual Color UnfocusedHighlightForegroundColor { get { return this . UnfocusedSelectedForeColor ; } set { this . UnfocusedSelectedForeColor = value ; } }
/// <summary>
/// ʹ <> <CAB9> UnfocusedSelectedForeColorOrDefault <20> <> <EFBFBD> <EFBFBD>
/// </summary>
[Obsolete("ʹ <> <CAB9> UnfocusedSelectedForeColorOrDefault <20> <> <EFBFBD> <EFBFBD> ")]
public virtual Color UnfocusedHighlightForegroundColorOrDefault { get { return this . UnfocusedSelectedForeColorOrDefault ; } }
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> а <EFBFBD> <D0B0> <EFBFBD> <EFBFBD> ڸ<EFBFBD> <DAB8> ƻ<EFBFBD> <C6BB> ϶<EFBFBD> <CFB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> ó<EFBFBD> <C3B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> ı <EFBFBD> <C4B1> <EFBFBD> ʾ <EFBFBD> <CABE> ʽ <EFBFBD> С <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> ΪFalse(Ĭ<> <C4AC> ֵ)<29> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɼ<EFBFBD> <C9BC> С <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> а <EFBFBD> <D0B0> <EFBFBD> <EFBFBD> ڸ<EFBFBD> <DAB8> ƻ<EFBFBD> <C6BB> ϶<EFBFBD> <CFB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> ó<EFBFBD> <C3B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> ı <EFBFBD> <C4B1> <EFBFBD> ʾ <EFBFBD> <CABE> ʽ <EFBFBD> С <EFBFBD> <D0A1> <EFBFBD> <EFBFBD> <EFBFBD> ΪFalse(Ĭ<> <C4AC> ֵ)<29> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɼ<EFBFBD> <C9BC> С <EFBFBD> " ) ,
DefaultValue ( false ) ]
public virtual bool IncludeHiddenColumnsInDataTransfer {
get { return includeHiddenColumnsInDataTransfer ; }
set { includeHiddenColumnsInDataTransfer = value ; }
}
private bool includeHiddenColumnsInDataTransfer ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ø<EFBFBD> <C3B8> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> ı <EFBFBD> <C4B1> С <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> ΪFalse(Ĭ<> <C4AC> ֵ)<29> <> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> <C4B1> н<EFBFBD> <D0BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> б <EFBFBD> <D0B1> ⡣
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> ı <EFBFBD> <C4B1> <EFBFBD> ." ) ,
DefaultValue ( false ) ]
public virtual bool IncludeColumnHeadersInCopy
{
get { return includeColumnHeadersInCopy ; }
set { includeColumnHeadersInCopy = value ; }
}
private bool includeColumnHeadersInCopy ;
/// <summary>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> <EFBFBD> ڽ<EFBFBD> <DABD> е <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> ༭<EFBFBD> <E0BCAD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> TRUE
/// </summary>
[Browsable(false)]
public virtual bool IsCellEditing {
get { return this . cellEditor ! = null ; }
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ڿ<EFBFBD> <DABF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> ObjectListView<65> <77> <EFBFBD> <EFBFBD> true<75> <65>
/// </summary>
[Browsable(false)]
public virtual bool IsDesignMode {
get { return this . DesignMode ; }
}
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> ǰ<EFBFBD> б <EFBFBD> <D0B1> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
virtual public bool IsFiltering {
get { return this . UseFiltering & & ( this . ModelFilter ! = null | | this . ListFilter ! = null ) ; }
}
/// <summary>
///<2F> <> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> м<EFBFBD> <D0BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ֵ<EFBFBD> Բ<EFBFBD> <D4B2> <EFBFBD> ƥ<EFBFBD> <C6A5> <EFBFBD>
///<2F> <> <EFBFBD> <EFBFBD> ΪFalse<73> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʲô<CAB2> <C3B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʼ <EFBFBD> <CABC> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD>
/// </summary>
/// <remarks>When this is true, the behavior is like that of ITunes.</remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> м<EFBFBD> <D0BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ֵ<EFBFBD> Բ<EFBFBD> <D4B2> <EFBFBD> ƥ<EFBFBD> <C6A5> <EFBFBD> <EFBFBD> <EEA3BF> <EFBFBD> <EFBFBD> ΪFalse<73> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʲô<CAB2> <C3B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʼ <EFBFBD> <CABC> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> " ) ,
DefaultValue ( true ) ]
public virtual bool IsSearchOnSortColumn {
get { return isSearchOnSortColumn ; }
set { isSearchOnSortColumn = value ; }
}
private bool isSearchOnSortColumn = true ;
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ô˿ؼ<CBBF> <D8BC> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʹ <EFBFBD> <CAB9> SimpleDropSink<6E> <6B> <EFBFBD> <EFBFBD> <EFBFBD> ϶<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>
/// <para>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> 滻<EFBFBD> κ<EFBFBD> <CEBA> <EFBFBD> ǰ<EFBFBD> <C7B0> DropSink<6E> <6B>
2021-01-12 08:32:13 +00:00
/// </para>
/// <para>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊtrue<75> <65> <EFBFBD> <EFBFBD> SimpleDropSink<6E> <6B> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> Ϊ˵<CEAA> <CBB5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> Խ<EFBFBD> <D4BD> <EFBFBD> <EFBFBD> ϶<EFBFBD> <CFB6> <EFBFBD>
/// <20> Լ<EFBFBD> <D4BC> <EFBFBD> <EFBFBD> ϶<EFBFBD> ijЩ<C4B3> <D0A9> <EFBFBD> <EFBFBD> ʱӦ<CAB1> <D3A6> ִ<EFBFBD> <D6B4> ʲô<CAB2> <C3B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫִ<D2AA> <D6B4> <EFBFBD> <EFBFBD> Щ<EFBFBD> <D0A9> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> Լ<EFBFBD> <D4BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ô<EFBFBD> :(
2021-01-12 08:32:13 +00:00
/// </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
2021-01-23 15:35:30 +00:00
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ô˿ؼ<CBBF> <D8BC> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʹ <EFBFBD> <CAB9> SimpleDropSink<6E> <6B> <EFBFBD> <EFBFBD> <EFBFBD> ϶<EFBFBD> " ) ,
2021-01-12 08:32:13 +00:00
DefaultValue ( false ) ]
public virtual bool IsSimpleDropSink {
get { return this . DropSink ! = null ; }
set {
this . DropSink = value ? new SimpleDropSink ( ) : null ;
}
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ô˿ؼ<CBBF> <D8BC> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʹ <EFBFBD> <CAB9> SimpleDragSource<63> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϶<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
/// <remarks><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> 滻֮ǰ<D6AE> <C7B0> <EFBFBD> κ<EFBFBD> DragSource</remarks>
2021-01-12 08:32:13 +00:00
[ Category ( "ObjectListView" ) ,
2021-01-23 15:35:30 +00:00
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ô˿ؼ<CBBF> <D8BC> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʹ <EFBFBD> <CAB9> SimpleDragSource<63> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϶<EFBFBD> " ) ,
2021-01-12 08:32:13 +00:00
DefaultValue ( false ) ]
public virtual bool IsSimpleDragSource {
get { return this . DragSource ! = null ; }
set {
this . DragSource = value ? new SimpleDragSource ( ) : null ;
}
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> Items<6D> <73> <EFBFBD> ϣ<EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> ڡ<EFBFBD> <DAA1> <EFBFBD> <EFBFBD> ԡ<EFBFBD> <D4A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> в<EFBFBD> <D0B2> ɼ<EFBFBD> <C9BC> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
new public ListViewItemCollection Items {
get { return base . Items ; }
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> б <EFBFBD> <D0B1> е <EFBFBD> <D0B5> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> ڷ<EFBFBD> <DAB7> <EFBFBD> ϸ<EFBFBD> <CFB8> ͼ<EFBFBD> <CDBC> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ⱦ<EFBFBD> <C8BE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <CFB8> Ϣ<EFBFBD> <CFA2> ͼ<EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е ij<D0B5> <C4B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
[ Category ( "ObjectListView" ) ,
2021-01-23 15:35:30 +00:00
Description ( "<22> <> <EFBFBD> б <EFBFBD> <D0B1> е <EFBFBD> <D0B5> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> ڷ<EFBFBD> <DAB7> <EFBFBD> ϸ<EFBFBD> <CFB8> ͼ<EFBFBD> <CDBC> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ⱦ<EFBFBD> <C8BE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <CFB8> Ϣ<EFBFBD> <CFA2> ͼ<EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е ij<D0B5> <C4B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
2021-01-12 08:32:13 +00:00
DefaultValue ( null ) ]
public IRenderer ItemRenderer {
get { return itemRenderer ; }
set { itemRenderer = value ; }
}
private IRenderer itemRenderer ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks><3E> <> <EFBFBD> <EFBFBD> PrimarySortColumn<6D> ı <EFBFBD> <C4B1> <EFBFBD> </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual OLVColumn LastSortColumn {
get { return this . PrimarySortColumn ; }
set { this . PrimarySortColumn = value ; }
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ķ<EFBFBD> <C4B7> <EFBFBD>
/// </summary>
/// <remarks><3E> <> <EFBFBD> <EFBFBD> PrimarySortOrder<65> ı <EFBFBD> <C4B1> <EFBFBD> </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual SortOrder LastSortOrder {
get { return this . PrimarySortOrder ; }
set { this . PrimarySortOrder = value ; }
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks>
/// <20> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Է<EFBFBD> ӳ<EFBFBD> <D3B3> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual IListFilter ListFilter {
get { return listFilter ; }
set {
listFilter = value ;
if ( this . UseFiltering )
this . UpdateFiltering ( ) ;
}
}
private IListFilter listFilter ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ÿ<EFBFBD> <C3BF> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1>
/// </summary>
/// <remarks>
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> <see cref="AdditionalFilter"/> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ǵ<EFBFBD> <C7B4> <EFBFBD> <EFBFBD> ԣ<EFBFBD>
/// <20> <> ΪAdditionalFilter<65> <72> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> ϡ<EFBFBD>
/// <20> <> <EFBFBD> ô<EFBFBD> <C3B4> <EFBFBD> <EFBFBD> <EFBFBD> ֻ<EFBFBD> <D6BB> <EFBFBD> 滻<EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ѹ<EFBFBD> <D1B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> κ<EFBFBD> <CEBA> <EFBFBD> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD> </para>
/// <para>
/// The list is updated immediately to reflect this filter.
/// </para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual IModelFilter ModelFilter {
get { return modelFilter ; }
set {
modelFilter = value ;
this . NotifyNewModelFilter ( ) ;
if ( this . UseFiltering ) {
this . UpdateFiltering ( ) ;
// When the filter changes, it's likely/possible that the selection has also changed.
// It's expensive to see if the selection has actually changed (for large virtual lists),
// so we just fake a selection changed event, just in case. SF #144
this . OnSelectedIndexChanged ( EventArgs . Empty ) ;
}
}
}
private IModelFilter modelFilter ;
/// <summary>
/// Gets the hit test info last time the mouse was moved.
/// </summary>
/// <remarks>Useful for hot item processing.</remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual OlvListViewHitTestInfo MouseMoveHitTest {
get { return mouseMoveHitTest ; }
private set { mouseMoveHitTest = value ; }
}
private OlvListViewHitTestInfo mouseMoveHitTest ;
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD>
/// </summary>
/// <remarks>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> .NET Groups<70> <73> <EFBFBD> ԵĹ<D4B5> <C4B9> <EFBFBD> <EFBFBD> <EFBFBD> ʽ <EFBFBD> <CABD> ͬ<EFBFBD> <CDAC> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊֻ<CEAA> <D6BB> <EFBFBD> <EFBFBD> <EFBFBD> ԡ<EFBFBD>
/// <20> <> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĸ<EFBFBD> <C4B8> IJ<EFBFBD> <C4B2> ᷴӳ<E1B7B4> <D3B3> ListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD>
/// <20> ڴ<EFBFBD> <DAB4> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ӻ<EFBFBD> ɾ<EFBFBD> <C9BE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> <C4A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> IJ<DEB8> <C4B2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> κ<EFBFBD> <CEBA> <EFBFBD> <EFBFBD> á<EFBFBD>
/// Ҫִ<D2AA> д<EFBFBD> <D0B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> BeforeCreatingGroups<70> <73> AboutToCreateGroups<70> ¼<EFBFBD> <C2BC> <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Щ<EFBFBD> ¼<EFBFBD> <C2BC> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public IList < OLVGroup > OLVGroups {
get { return this . olvGroups ; }
set { this . olvGroups = value ; }
}
private IList < OLVGroup > olvGroups ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ۵ <EFBFBD> <DBB5> <EFBFBD> OLVGroups<70> ļ<EFBFBD> <C4BC> ϡ<EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public IEnumerable < OLVGroup > CollapsedGroups {
get
{
if ( this . OLVGroups ! = null )
{
foreach ( OLVGroup group in this . OLVGroups )
{
if ( group . Collapsed )
yield return group ;
}
}
}
set
{
if ( this . OLVGroups = = null )
return ;
Hashtable shouldCollapse = new Hashtable ( ) ;
if ( value ! = null )
{
foreach ( OLVGroup group in value )
shouldCollapse [ group . Key ] = true ;
}
foreach ( OLVGroup group in this . OLVGroups )
{
group . Collapsed = shouldCollapse . ContainsKey ( group . Key ) ;
}
}
}
/// <summary>
/// Gets or sets whether the user wants to owner draw the header control
/// themselves. If this is false (the default), ObjectListView will use
/// custom drawing to render the header, if needed.
/// </summary>
/// <remarks>
/// If you listen for the DrawColumnHeader event, you need to set this to true,
/// otherwise your event handler will not be called.
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "Should the DrawColumnHeader event be triggered" ) ,
DefaultValue ( false ) ]
public bool OwnerDrawnHeader {
get { return ownerDrawnHeader ; }
set { ownerDrawnHeader = value ; }
}
private bool ownerDrawnHeader ;
/// <summary>
///<2F> <> ȡ/<2F> <> <EFBFBD> ô<EFBFBD> <C3B4> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> Ķ<EFBFBD> <C4B6> <EFBFBD>
/// </summary>
/// <remarks>
/// <para>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> ô<EFBFBD> <C3B4> <EFBFBD> <EFBFBD> Ժؼ<F3A3ACBF> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ݽ<EFBFBD> <DDBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ¡<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </para>
2021-09-12 06:54:13 +00:00
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ܣ<EFBFBD> <DCA3> ˷<EFBFBD> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> ݡ<EFBFBD> ʹ <EFBFBD> <CAB9> <see cref="SetObjects(IEnumerable, bool)"/> if
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 뱣<EFBFBD> <EBB1A3> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> ݣ<EFBFBD> <DDA3> <EFBFBD> ִ<EFBFBD> <D6B4> <EFBFBD> <EFBFBD> <EFBFBD> ²<EFBFBD> <C2B2> <EFBFBD> <EFBFBD> <EFBFBD>
///<2F> <> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> Ǹô<C7B8> <C3B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> IJ<EFBFBD> <C4B2> ֣<EFBFBD> <D6A3> <EFBFBD> <EFBFBD> <EFBFBD> ΪO(N)<29> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> n<EFBFBD> <6E> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> </para>
/// <para><3E> ˷<EFBFBD> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ̰߳<DFB3> ȫ<EFBFBD> ġ<EFBFBD> </para>
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȷʵ<C8B7> <CAB5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> <C4A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ի<EFBFBD> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> 1000<30> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫһ Щʱ<D0A9> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> ܷ<EFBFBD> <DCB7> ء<EFBFBD> </para>
/// <para><3E> ˼<EFBFBD> <CBBC> <EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1> ʹ <EFBFBD> <CAB9> <see cref="FilteredObjects"/> ֻ<> <D6BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Щ<EFBFBD> <D0A9> <EFBFBD> κ<EFBFBD> <CEBA> Ѱ<EFBFBD> װ<EFBFBD> <D7B0> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> Ҵ<EFBFBD> <D2B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ķ<EFBFBD> <C4B6> <EFBFBD> <EFBFBD> <EFBFBD> </para>
2021-01-12 08:32:13 +00:00
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual IEnumerable Objects {
get { return this . objects ; }
set { this . SetObjects ( value , true ) ; }
}
private IEnumerable objects ;
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> ǰ<EFBFBD> ؼ<EFBFBD> <D8BC> <EFBFBD> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɵ<EFBFBD> <C9B5> б <EFBFBD>
/// </summary>
public virtual IList ObjectsList
{
get
{
var enumer = this . objects . GetEnumerator ( ) ;
ArrayList list = new ArrayList ( ) ;
while ( enumer . MoveNext ( ) )
{
list . Add ( enumer . Current ) ;
}
return list ;
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> Ⱥ<EFBFBD> <C8BA> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> ǵĶ<C7B5> <C4B6> ϡ<F3BCAFBA>
/// (<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Excel<65> <6C> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1> )
2021-01-12 08:32:13 +00:00
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual IEnumerable ObjectsForClustering {
get { return this . Objects ; }
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> ListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƶ<EFBFBD> ͼ<EFBFBD> <CDBC>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> ListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƶ<EFBFBD> ͼ<EFBFBD> <CDBC> " ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Content ) ]
public ImageOverlay OverlayImage {
get { return this . imageOverlay ; }
set {
if ( this . imageOverlay = = value )
return ;
this . RemoveOverlay ( this . imageOverlay ) ;
this . imageOverlay = value ;
this . AddOverlay ( this . imageOverlay ) ;
}
}
private ImageOverlay imageOverlay ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> ListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƶ<EFBFBD> <C6B5> ı <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> ListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƶ<EFBFBD> <C6B5> ı <EFBFBD> " ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Content ) ]
public TextOverlay OverlayText {
get { return this . textOverlay ; }
set {
if ( this . textOverlay = = value )
return ;
this . RemoveOverlay ( this . textOverlay ) ;
this . textOverlay = value ;
this . AddOverlay ( this . textOverlay ) ;
}
}
private TextOverlay textOverlay ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> и<EFBFBD> <D0B8> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <CDB8> <EFBFBD> ȡ<EFBFBD> 0<EFBFBD> <30> ʾ <EFBFBD> <CABE> ȫ<C8AB> <CDB8> <EFBFBD> <EFBFBD> 255<35> <35> ʾ <EFBFBD> <CABE> ȫ<EFBFBD> <C8AB> <EFBFBD> <CDB8> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks>
///<2F> <> <EFBFBD> Ѿ<EFBFBD> <D1BE> <EFBFBD> ʱ<EFBFBD> ˣ<EFBFBD> <CBA3> <EFBFBD> <EFBFBD> <EFBFBD> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> Transparency<63> <79>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public int OverlayTransparency {
get { return this . overlayTransparency ; }
set { this . overlayTransparency = Math . Min ( 255 , Math . Max ( 0 , value ) ) ; }
}
private int overlayTransparency = 128 ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> ListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƶĸ<C6B5> <C4B8> <EFBFBD> <EFBFBD> б <EFBFBD>
/// </summary>
/// <remarks>
/// You can add new overlays and remove overlays that you have added, but
/// don't mess with the overlays that you didn't create.
/// </remarks>
[Browsable(false)]
protected IList < IOverlay > Overlays {
get { return this . overlays ; }
}
private readonly List < IOverlay > overlays = new List < IOverlay > ( ) ;
/// <summary>
/// Gets or sets whether the ObjectListView will be owner drawn. Defaults to true.
/// </summary>
/// <remarks>
/// <para>
/// When this is true, all of ObjectListView's neat features are available.
/// </para>
/// <para>We have to reimplement this property, even though we just call the base
/// property, in order to change the [DefaultValue] to true.
/// </para>
/// </remarks>
[ Category ( "Appearance" ) ,
Description ( "Should the ListView do its own rendering" ) ,
DefaultValue ( true ) ]
public new bool OwnerDraw {
get { return base . OwnerDraw ; }
set { base . OwnerDraw = value ; }
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɺ<EFBFBD> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5>
/// </summary>
/// <remarks>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Խ<EFBFBD> <D4BD> <EFBFBD> δ<EFBFBD> <CEB4> ʽ <EFBFBD> <CABD> <EFBFBD> <EFBFBD> CheckStateGetter/Putterʱ<72> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> á<EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> CheckStateGetter/Putter<65> <72> <EFBFBD> <EFBFBD> ô<EFBFBD> <C3B4> Щ<EFBFBD> <D0A9> <EFBFBD> <EFBFBD> <EFBFBD> Ѿ<EFBFBD> <D1BE> ־û<D6BE> <C3BB> <EFBFBD> <EFBFBD> е ļ<D0B5> <C4BC> <EFBFBD> <EFBFBD> ԡ<EFBFBD>
/// </para>
/// <para><3E> <> Ĭ<EFBFBD> <C4AC> ֵΪtrue<75> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪFalse<73> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɻ<EFBFBD> ɸѡ <C9B8> б <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <EFBFBD> ʧ<EFBFBD> <CAA7> ֵ<EFBFBD> <D6B5>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> н<EFBFBD> <D0BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊfalse<73> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 밲װCheckStateGetter/Putters<72> <73> </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɺ<EFBFBD> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> ֵ" ) ,
DefaultValue ( true ) ]
public virtual bool PersistentCheckBoxes {
get { return persistentCheckBoxes ; }
set {
if ( persistentCheckBoxes = = value )
return ;
persistentCheckBoxes = value ;
this . ClearPersistentCheckState ( ) ;
}
}
private bool persistentCheckBoxes = true ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ü<EFBFBD> ס ģ<D7A1> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> ĸ<EFBFBD> ѡ <EFBFBD> <D1A1> ״̬<D7B4> <CCAC> <EFBFBD> ֵ<EFBFBD>
/// </summary>
/// <remarks><3E> <> PersistentCheckBoxsֵΪTRUEʱ<45> <CAB1> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> .</remarks>
protected Dictionary < Object , CheckState > CheckStateMap {
get { return checkStateMap ? ? ( checkStateMap = new Dictionary < object , CheckState > ( ) ) ; }
set { checkStateMap = value ; }
}
private Dictionary < Object , CheckState > checkStateMap ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual OLVColumn PrimarySortColumn {
get { return this . primarySortColumn ; }
set {
this . primarySortColumn = value ;
if ( this . TintSortColumn )
this . SelectedColumn = value ;
}
}
private OLVColumn primarySortColumn ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ķ<EFBFBD> <C4B7> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual SortOrder PrimarySortOrder {
get { return primarySortOrder ; }
set { primarySortOrder = value ; }
}
private SortOrder primarySortOrder ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ò<EFBFBD> <C3B2> ɱ༭<C9B1> <E0BCAD> ѡ <EFBFBD> <D1A1> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> á<EFBFBD> Ĭ<EFBFBD> <C4AC> <EFBFBD> <EFBFBD> false<73> <65>
/// </summary>
/// <remarks>
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģʽ (owner drawn mode)<29> <> <EFBFBD> <EFBFBD> Ч<EFBFBD> <D0A7> </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ò<EFBFBD> <C3B2> ɱ༭<C9B1> <E0BCAD> ѡ <EFBFBD> <D1A1> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( false ) ]
public virtual bool RenderNonEditableCheckboxesAsDisabled {
get { return renderNonEditableCheckboxesAsDisabled ; }
set { renderNonEditableCheckboxesAsDisabled = value ; }
}
private bool renderNonEditableCheckboxesAsDisabled ;
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> λָ<CEBB> <D6B8> <EFBFBD> ؼ<EFBFBD> <D8BC> <EFBFBD> ÿ<EFBFBD> е ĸ߶ȡ<DFB6>
/// </summary>
/// <remarks><para><3E> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> е <EFBFBD> <D0B5> и<EFBFBD> ͨ<EFBFBD> <CDA8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> <D0A1> С ͼ<D0A1> <CDBC> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> С <EFBFBD> <D0A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ǹü<C7B8> <C3BC> <EFBFBD> (ԭ<> <D4AD> <EFBFBD> ǣ<EFBFBD> <C7A3> <EFBFBD> <EFBFBD> <EFBFBD> Ȼ<EFBFBD> <C8BB> <EFBFBD> ܽ<EFBFBD> <DCBD> и<EFBFBD> <D0B8> <EFBFBD> <EFBFBD> <EFBFBD> ΪС <CEAA> ڿؼ<DABF> <D8BC> <EFBFBD> ʹ <EFBFBD> õ<EFBFBD> <C3B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> и<EFBFBD> )<29> <> </para>
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ-1<> <31> ʾ ʹ <CABE> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㷽<EFBFBD> <E3B7BD> <EFBFBD> <EFBFBD> </para>
/// <para><bold><3E> ˹<EFBFBD> <CBB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 鹦<EFBFBD> ܣ<EFBFBD> </bold><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ô˹<C3B4> <CBB9> ܣ<EFBFBD> <DCA3> <EFBFBD> <EFBFBD> ij<EFBFBD> <C4B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ܻᷢ<DCBB> <E1B7A2> <EFBFBD> <EFBFBD> <EFBFBD> 벻<EFBFBD> <EBB2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 顣</para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> λָ<CEBB> <D6B8> <EFBFBD> ؼ<EFBFBD> <D8BC> <EFBFBD> ÿ<EFBFBD> е ĸ߶<C4B8> " ) ,
DefaultValue ( - 1 ) ]
public virtual int RowHeight {
get { return rowHeight ; }
set {
if ( value < 1 )
rowHeight = - 1 ;
else
rowHeight = value ;
if ( this . DesignMode )
return ;
this . SetupBaseImageList ( ) ;
if ( this . CheckBoxes )
this . InitializeStateImageList ( ) ;
}
}
private int rowHeight = - 1 ;
/// <summary>
/// <20> <> ȡÿ<C8A1> <C3BF> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ظ<EFBFBD>
/// </summary>
[Browsable(false)]
public virtual int RowHeightEffective {
get {
switch ( this . View ) {
case View . List :
case View . SmallIcon :
case View . Details :
return Math . Max ( this . SmallImageSize . Height , this . Font . Height ) ;
case View . Tile :
return this . TileSize . Height ;
case View . LargeIcon :
if ( this . LargeImageList = = null )
return this . Font . Height ;
return Math . Max ( this . LargeImageList . ImageSize . Height , this . Font . Height ) ;
default :
// This should never happen
return 0 ;
}
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> ˿ؼ<CBBF> <D8BC> <EFBFBD> ÿҳ<C3BF> <D2B3> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[Browsable(false)]
public virtual int RowsPerPage {
get {
return NativeMethods . GetCountPerPage ( this ) ;
}
}
/// <summary>
///<2F> <> ȡ/<2F> <> <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> <EFBFBD> ڽ<EFBFBD> <DABD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> ȵı Ƚϵ<C8BD> <CFB5> <EFBFBD> (<28> ڶ<EFBFBD> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )<29> <>
/// </summary>
/// <remarks><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> 档<EFBFBD> <E6A1A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ա<EFBFBD> <D4B1> ̷<EFBFBD> ʽ <EFBFBD> <CABD> <EFBFBD> á<EFBFBD> </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual OLVColumn SecondarySortColumn {
get { return this . secondarySortColumn ; }
set { this . secondarySortColumn = value ; }
}
private OLVColumn secondarySortColumn ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> ʹ <EFBFBD> <CAB9> Second darySortColumnʱ<6E> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʲô˳<C3B4> <CBB3> <EFBFBD> ȽϽ<C8BD> <CFBD> <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual SortOrder SecondarySortOrder {
get { return this . secondarySortOrder ; }
set { this . secondarySortOrder = value ; }
}
private SortOrder secondarySortOrder = SortOrder . None ;
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> û<EFBFBD> <C3BB> <EFBFBD> Ctrl+A<> <41> <EFBFBD> ϼ<EFBFBD> ʱ<EFBFBD> Ƿ<EFBFBD> Ӧѡ <D3A6> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> û<EFBFBD> <C3BB> <EFBFBD> Ctrl+A<> <41> <EFBFBD> ϼ<EFBFBD> ʱ<EFBFBD> Ƿ<EFBFBD> Ӧѡ <D3A6> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( true ) ]
public virtual bool SelectAllOnControlA {
get { return selectAllOnControlA ; }
set { selectAllOnControlA = value ; }
}
private bool selectAllOnControlA = true ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> û<EFBFBD> <C3BB> Ҽ<EFBFBD> <D2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ʾ һ <CABE> <D2BB> <EFBFBD> ˵<EFBFBD> <CBB5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> ͼ<EFBFBD> н<EFBFBD> <D0BD> <EFBFBD> ʾ <EFBFBD> <CABE> Щ<EFBFBD> <D0A9>
/// </summary>
/// <remarks><3E> <> ֻ<EFBFBD> <D6BB> SelectColumnsOnRightClickBehaviour<75> ļ<EFBFBD> <C4BC> <EFBFBD> <EFBFBD> <EFBFBD> װ<EFBFBD> <D7B0> <EFBFBD> <EFBFBD> .</remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> û<EFBFBD> <C3BB> Ҽ<EFBFBD> <D2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ʾ һ <CABE> <D2BB> <EFBFBD> ˵<EFBFBD> <CBB5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> ͼ<EFBFBD> н<EFBFBD> <D0BD> <EFBFBD> ʾ <EFBFBD> <CABE> Щ<EFBFBD> <D0A9> " ) ,
DefaultValue ( true ) ]
public virtual bool SelectColumnsOnRightClick {
get { return this . SelectColumnsOnRightClickBehaviour ! = ColumnSelectBehaviour . None ; }
set {
if ( value ) {
if ( this . SelectColumnsOnRightClickBehaviour = = ColumnSelectBehaviour . None )
this . SelectColumnsOnRightClickBehaviour = ColumnSelectBehaviour . InlineMenu ;
} else {
this . SelectColumnsOnRightClickBehaviour = ColumnSelectBehaviour . None ;
}
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> Ҽ<EFBFBD> <D2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ܹ<EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> Ҽ<EFBFBD> <D2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ܹ<EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( ColumnSelectBehaviour . InlineMenu ) ]
public virtual ColumnSelectBehaviour SelectColumnsOnRightClickBehaviour {
get { return selectColumnsOnRightClickBehaviour ; }
set { selectColumnsOnRightClickBehaviour = value ; }
}
private ColumnSelectBehaviour selectColumnsOnRightClickBehaviour = ColumnSelectBehaviour . InlineMenu ;
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> ˵<EFBFBD> <CBB5> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> ִ<F3B1A3B3> <D6B4> <EFBFBD> ״̬<D7B4> <CCAC> <EFBFBD> <EFBFBD> <EFBFBD> ִ<EFBFBD> <D6B4> <EFBFBD> ״̬<D7B4> <CCAC> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> һ <EFBFBD> δ<CEB4> <F2BFAABB> رն<D8B1> <D5B6> <EFBFBD> <EFBFBD> С <EFBFBD>
/// </summary>
/// <remarks>SelectColumnsOnRightClickBehaviour<75> <72> <EFBFBD> <EFBFBD> ΪInlineMenuʱ<75> <CAB1> <EFBFBD> <EFBFBD> Ч<EFBFBD> <D0A7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> ΪSubMenu<6E> ˵<EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <EFBFBD> <EEB2BB> <EFBFBD> <EFBFBD> <EFBFBD> á<EFBFBD> </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> ˵<EFBFBD> <CBB5> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> ִ<F3B1A3B3> <D6B4> <EFBFBD> ״̬<D7B4> <CCAC> <EFBFBD> <EFBFBD> <EFBFBD> ִ<EFBFBD> <D6B4> <EFBFBD> ״̬<D7B4> <CCAC> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> һ <EFBFBD> δ<CEB4> <F2BFAABB> رն<D8B1> <D5B6> <EFBFBD> <EFBFBD> С <EFBFBD> " ) ,
DefaultValue ( true ) ]
public virtual bool SelectColumnsMenuStaysOpen {
get { return selectColumnsMenuStaysOpen ; }
set { selectColumnsMenuStaysOpen = value ; }
}
private bool selectColumnsMenuStaysOpen = true ;
/// <summary>
2021-09-12 06:54:13 +00:00
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>
/// <para>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> TintSortColumnΪtrue<75> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> н<EFBFBD> <D0BD> Զ<EFBFBD> <D4B6> <EFBFBD> Ϊѡ <CEAA> <D1A1> <EFBFBD> С <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </para>
/// <para>
2021-09-12 06:54:13 +00:00
/// ɫ<> <C9AB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɫ<EFBFBD> <C9AB> SelectedColumnTint<6E> <74> <EFBFBD> ơ<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public OLVColumn SelectedColumn {
get { return this . selectedColumn ; }
set {
this . selectedColumn = value ;
if ( value = = null ) {
this . RemoveDecoration ( this . selectedColumnDecoration ) ;
} else {
if ( ! this . HasDecoration ( this . selectedColumnDecoration ) )
this . AddDecoration ( this . selectedColumnDecoration ) ;
}
}
}
private OLVColumn selectedColumn ;
private readonly TintedColumnDecoration selectedColumnDecoration = new TintedColumnDecoration ( ) ;
/// <summary>
/// Gets or sets the decoration that will be drawn on all selected rows
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual IDecoration SelectedRowDecoration {
get { return this . selectedRowDecoration ; }
set { this . selectedRowDecoration = value ; }
}
private IDecoration selectedRowDecoration ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> ʲô<CAB2> <C3B4> ɫ<EFBFBD> <C9AB> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɫ
/// </summary>
/// <remarks>
/// ɫ<> <C9AB> <EFBFBD> <EFBFBD> ɫ<EFBFBD> <C9AB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Alpha<68> ɻ<EFBFBD> <C9BB> ϵģ<CFB5> <C4A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɫ<EFBFBD> Ǵ<EFBFBD> ɫ(<28> <> Alpha=255)<29> <> <EFBFBD> <EFBFBD> <EFBFBD> Ὣ<EFBFBD> <E1BDAB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> к<EFBFBD> <D0BA> <EFBFBD> <EFBFBD> <EFBFBD> Alphaֵ<61> <D6B5>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> ʲô<CAB2> <C3B4> ɫ<EFBFBD> <C9AB> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɫ" ) ,
DefaultValue ( typeof ( Color ) , "" ) ]
public virtual Color SelectedColumnTint {
get { return selectedColumnTint ; }
set {
this . selectedColumnTint = value . A = = 255 ? Color . FromArgb ( 15 , value ) : value ;
this . selectedColumnDecoration . Tint = this . selectedColumnTint ;
}
}
private Color selectedColumnTint = Color . Empty ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> ǰѡ <C7B0> <D1A1> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> ѡ <EFBFBD> <D1A1> <EFBFBD> κ<EFBFBD> <CEBA> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> ˶<EFBFBD> <CBB6> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> -1<> <31>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual int SelectedIndex {
get { return this . SelectedIndices . Count = = 1 ? this . SelectedIndices [ 0 ] : - 1 ; }
set {
this . SelectedIndices . Clear ( ) ;
if ( value > = 0 & & value < this . Items . Count )
this . SelectedIndices . Add ( value ) ;
}
}
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> ǰѡ <C7B0> <D1A1> <EFBFBD> <EFBFBD> ListViewItem<65> <6D> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> δѡ <CEB4> <D1A1> <EFBFBD> κ<EFBFBD> <CEBA> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> ˶<EFBFBD> <CBB6> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> NULL<4C> <4C>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual OLVListItem SelectedItem {
get {
return this . SelectedIndices . Count = = 1 ? this . GetItem ( this . SelectedIndices [ 0 ] ) : null ;
}
set {
this . SelectedIndices . Clear ( ) ;
if ( value ! = null )
this . SelectedIndices . Add ( value . Index ) ;
}
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> ֻѡ <D6BB> <D1A1> <EFBFBD> <EFBFBD> һ <EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> ӵ<EFBFBD> ǰѡ <C7B0> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> л<EFBFBD> ȡģ<C8A1> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> δѡ <CEB4> <D1A1> <EFBFBD> κ<EFBFBD> <CEBA> У <EFBFBD> <D0A3> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> ˶<EFBFBD> <CBB6> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> NULL<4C> <4C>
/// <20> <> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> ⽫ѡ <E2BDAB> <D1A1> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڸ<EFBFBD> <DAB8> <EFBFBD> <EFBFBD> ϣ<EFBFBD> ȡ<EFBFBD> <C8A1> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual Object SelectedObject {
get {
return this . SelectedIndices . Count = = 1 ? this . GetModelObject ( this . SelectedIndices [ 0 ] ) : null ;
}
set {
// If the given model is already selected, don't do anything else (prevents an flicker)
object selectedObject = this . SelectedObject ;
if ( selectedObject ! = null & & selectedObject . Equals ( value ) )
return ;
this . SelectedIndices . Clear ( ) ;
this . SelectObject ( value , true ) ;
}
}
/// <summary>
/// <20> ӵ<EFBFBD> ǰѡ <C7B0> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> л<EFBFBD> ȡģ<C8A1> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> δѡ <CEB4> <D1A1> <EFBFBD> κ<EFBFBD> <CEBA> У <EFBFBD> <D0A3> ص<F2B7B5BB> <D8B5> б <EFBFBD> Ϊ<EFBFBD> ա <EFBFBD>
/// <20> <> <EFBFBD> ô<EFBFBD> ֵʱ<D6B5> <CAB1> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> У <EFBFBD> ȡ<EFBFBD> <C8A1> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD>
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual IList SelectedObjects {
get {
ArrayList list = new ArrayList ( ) ;
foreach ( int index in this . SelectedIndices )
list . Add ( this . GetModelObject ( index ) ) ;
return list ;
}
set {
this . SelectedIndices . Clear ( ) ;
this . SelectObjects ( value ) ;
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> û<EFBFBD> <C3BB> Ҽ<EFBFBD> <D2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ʾ һ <CABE> <D2BB> <EFBFBD> ˵<EFBFBD> <CBB5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> Ҫ<EFBFBD> <D2AA> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> ִ<EFBFBD> е ij<D0B5> <C4B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> û<EFBFBD> <C3BB> Ҽ<EFBFBD> <D2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ʾ һ <CABE> <D2BB> <EFBFBD> ˵<EFBFBD> <CBB5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> Ҫ<EFBFBD> <D2AA> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> ִ<EFBFBD> е ij<D0B5> <C4B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( false ) ]
public virtual bool ShowCommandMenuOnRightClick {
get { return showCommandMenuOnRightClick ; }
set { showCommandMenuOnRightClick = value ; }
}
private bool showCommandMenuOnRightClick ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> <C3B5> Ҽ<EFBFBD> <D2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ؼ<EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> ObjectListView<65> Ƿ<EFBFBD> <C7B7> <EFBFBD> ɸѡ <C9B8> ˵<EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> <EFBFBD> ΪTrue<75> <65> <EFBFBD> <EFBFBD> <EFBFBD> Ҽ<EFBFBD> <D2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> ⽫<EFBFBD> <E2BDAB> ʾ ɸѡ <C9B8> <D1A1> <EFBFBD> ˵<EFBFBD> ѡ <EFBFBD> <D1A1> " ) ,
DefaultValue ( true ) ]
public bool ShowFilterMenuOnRightClick {
get { return showFilterMenuOnRightClick ; }
set { showFilterMenuOnRightClick = value ; }
}
private bool showFilterMenuOnRightClick = true ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> Ŀ
/// </summary>
[ Category ( "Appearance" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> Ŀ" ) ,
2021-09-12 06:54:13 +00:00
DefaultValue ( false ) ]
2021-01-12 08:32:13 +00:00
new public virtual bool ShowGroups {
get { return base . ShowGroups ; }
set {
this . GroupImageList = this . GroupImageList ;
base . ShowGroups = value ;
}
}
/// <summary>
/// <20> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ λͼ<CEBB> <CDBC> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks>
/// The only reason for not wanting to have sort indicators is that, on pre-XP versions of
/// Windows, having sort indicators required the ListView to have a small image list, and
/// as soon as you give a ListView a SmallImageList, the text of column 0 is bumped 16
/// pixels to the right, even if you never used an image.
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ λͼ<CEBB> <CDBC> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( true ) ]
public virtual bool ShowSortIndicators {
get { return showSortIndicators ; }
set { showSortIndicators = value ; }
}
private bool showSortIndicators ;
/// <summary>
/// <20> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> ϵ<EFBFBD> ͼ<EFBFBD> <CDBC>
/// </summary>
/// <remarks>
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <DFBB> Ƶģ<C6B5> <C4A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ ͼ<CABE> <CDBC> </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> ϵ<EFBFBD> ͼ<EFBFBD> <CDBC> " ) ,
DefaultValue ( false ) ]
public virtual bool ShowImagesOnSubItems {
get { return showImagesOnSubItems ; }
set {
showImagesOnSubItems = value ;
if ( this . Created )
this . ApplyExtendedStyles ( ) ;
if ( value & & this . VirtualMode )
this . OwnerDraw = true ;
}
}
private bool showImagesOnSubItems ;
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Կ<EFBFBD> <D4BF> Ʒ <EFBFBD> <C6B7> <EFBFBD> <EFBFBD> <EFBFBD> ǩ<EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʾ <EFBFBD> ÷<EFBFBD> <C3B7> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks>
///<2F> <> <EFBFBD> ĸ<EFBFBD> ʽ <EFBFBD> <CABD> GroupWithItemCountFormat/GroupWithItemCountSingularFormat<61> <74> <EFBFBD> Կ<EFBFBD> <D4BF> <EFBFBD>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> <EFBFBD> <EFBFBD> Կ<EFBFBD> <D4BF> Ʒ <EFBFBD> <C6B7> <EFBFBD> <EFBFBD> <EFBFBD> ǩ<EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʾ <EFBFBD> ÷<EFBFBD> <C3B7> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( false ) ]
public virtual bool ShowItemCountOnGroups {
get { return showItemCountOnGroups ; }
set { showItemCountOnGroups = value ; }
}
private bool showItemCountOnGroups ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ÿؼ<C3BF> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʾ <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> (True)<29> <> <EFBFBD> <EFBFBD> <EFBFBD> ǽ<EFBFBD> <C7BD> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <CFB8> Ϣ<EFBFBD> <CFA2> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʾ <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> (False)
/// </summary>
/// <remarks>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Թ<EFBFBD> <D4B9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> JPP 2010/04/06<30> <36>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڴ<EFBFBD> <DAB4> <EFBFBD> <EFBFBD> ؼ<EFBFBD> ֮ǰ<D6AE> <C7B0> <EFBFBD> õģ<C3B5> <C4A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// <20> <> <EFBFBD> ǣ<EFBFBD> <C7A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڴ<EFBFBD> <DAB4> <EFBFBD> <EFBFBD> ؼ<EFBFBD> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> رգ <D8B1> <D5A3> <EFBFBD> <EFBFBD> ؼ<EFBFBD> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> ʧ<EFBFBD> 临ѡ <E4B8B4> <D1A1> (<28> <> <EFBFBD> ֣<EFBFBD> )
/// </para>
/// <para>
/// Ҫ<> ڴ<EFBFBD> <DAB4> <EFBFBD> <EFBFBD> ؼ<EFBFBD> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĵ<EFBFBD> <C4B4> <EFBFBD> <EFBFBD> ã<EFBFBD> <C3A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ܸ<EFBFBD> <DCB8> ӡ<EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǹرյģ<D5B5> <C4A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> DZ<EFBFBD> <C7B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͻ<EFBFBD> <CDBB> <EFBFBD> <EFBFBD> ֡<EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> <EFBFBD> ڴ<EFBFBD> <DAB4> <EFBFBD> ״̬<D7B4> <CCAC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> رգ <D8B1> <D5A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> ´ <EFBFBD> <C2B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʊ<EFBFBD> <C6B1> <EFBFBD>
/// <20> <> <EFBFBD> ´ <EFBFBD> <C2B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> ⣬<EFBFBD> <E2A3AC> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> ǵĸ<C7B5> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> ʽ <EFBFBD> <CABD> ʧ<EFBFBD> <CAA7>
/// </para>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Բ<EFBFBD> <D4B2> ܹ<EFBFBD> <DCB9> <EFBFBD> <EFBFBD> <EFBFBD> Win XP ϵͳ.</para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ÿؼ<C3BF> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʾ <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> (True)<29> <> <EFBFBD> <EFBFBD> <EFBFBD> ǽ<EFBFBD> <C7BD> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <CFB8> Ϣ<EFBFBD> <CFA2> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʾ <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> (False)" ) ,
DefaultValue ( true ) ]
public bool ShowHeaderInAllViews {
get { return ObjectListView . IsVistaOrLater & & showHeaderInAllViews ; }
set {
if ( showHeaderInAllViews = = value )
return ;
showHeaderInAllViews = value ;
// If the control isn't already created, everything is fine.
if ( ! this . Created )
return ;
// If the header is being hidden, we have to recreate the control
// to remove the style (not sure why this is)
if ( showHeaderInAllViews )
this . ApplyExtendedStyles ( ) ;
else
this . RecreateHandle ( ) ;
// Still more complications. The change doesn't become visible until the View is changed
if ( this . View ! = View . Details ) {
View temp = this . View ;
this . View = View . Details ;
this . View = temp ;
}
}
}
private bool showHeaderInAllViews = true ;
/// <summary>
///<2F> <> дSmallImageList<73> <74> <EFBFBD> ԣ<EFBFBD> <D4A3> Ա<EFBFBD> <D4B1> <EFBFBD> <EFBFBD> ǿ<EFBFBD> <C7BF> <EFBFBD> <EFBFBD> <EFBFBD> ȷ<EFBFBD> <C8B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks><para><3E> <> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> RowHeight<68> <74> <EFBFBD> <EFBFBD> ָ<EFBFBD> <D6B8> <EFBFBD> иߣ<D0B8> <DFA3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> /<2F> <> <EFBFBD> <EFBFBD> RowHeight֮ǰ<D6AE> <C7B0> ȫ<EFBFBD> <C8AB> ʼ <EFBFBD> <CABC> SmallImageList<73> <74>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> и<EFBFBD> ֮<EFBFBD> <D6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> ӵ<EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ٴν <D9B4> ͼ<EFBFBD> <CDBC> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ؼ<EFBFBD> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <F2B5A5B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ч<EFBFBD> ģ<EFBFBD>
/// <code>listView1.SmallImageList = listView1.SmallImageList;</code></para>
/// </remarks>
new public ImageList SmallImageList {
get { return this . shadowedImageList ; }
set {
this . shadowedImageList = value ;
if ( this . UseSubItemCheckBoxes )
this . SetupSubItemCheckBoxes ( ) ;
this . SetupBaseImageList ( ) ;
}
}
private ImageList shadowedImageList ;
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> С ͼ<D0A1> <CDBC> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> Ĵ<EFBFBD> С <EFBFBD> <D0A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> ֵ
/// </summary>
[Browsable(false)]
public virtual Size SmallImageSize {
get {
return this . BaseSmallImageList = = null ? new Size ( 16 , 16 ) : this . BaseSmallImageList . ImageSize ;
}
}
/// <summary>
/// <20> <> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> ð<EFBFBD> <C3B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪFalse<73> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> ͬһ <CDAC> н<EFBFBD> <D0BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> ð<EFBFBD> <C3B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪFalse<73> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> ͬһ <CDAC> н<EFBFBD> <D0BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( true ) ]
public virtual bool SortGroupItemsByPrimaryColumn {
get { return this . sortGroupItemsByPrimaryColumn ; }
set { this . sortGroupItemsByPrimaryColumn = value ; }
}
private bool sortGroupItemsByPrimaryColumn = true ;
/// <summary>
///<2F> <> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĩβ<C4A9> <CEB2> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> ͷ֮<CDB7> <D6AE> Ӧ<EFBFBD> <D3A6> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĩβ<C4A9> <CEB2> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> ͷ֮<CDB7> <D6AE> Ӧ<EFBFBD> <D3A6> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( 0 ) ]
public virtual int SpaceBetweenGroups {
get { return this . spaceBetweenGroups ; }
set {
if ( this . spaceBetweenGroups = = value )
return ;
this . spaceBetweenGroups = value ;
this . SetGroupSpacing ( ) ;
}
}
private int spaceBetweenGroups ;
private void SetGroupSpacing ( ) {
if ( ! this . IsHandleCreated )
return ;
NativeMethods . LVGROUPMETRICS metrics = new NativeMethods . LVGROUPMETRICS ( ) ;
metrics . cbSize = ( ( uint ) Marshal . SizeOf ( typeof ( NativeMethods . LVGROUPMETRICS ) ) ) ;
metrics . mask = ( uint ) GroupMetricsMask . LVGMF_BORDERSIZE ;
metrics . Bottom = ( uint ) this . SpaceBetweenGroups ;
NativeMethods . SetGroupMetrics ( this , metrics ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <CEA2> ɫ<EFBFBD> <C9AB> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
[ Category ( "ObjectListView" ) ,
2021-01-23 15:35:30 +00:00
Description ( "<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <CEA2> ɫ<EFBFBD> <C9AB> " ) ,
2021-01-12 08:32:13 +00:00
DefaultValue ( false ) ]
public virtual bool TintSortColumn {
get { return this . tintSortColumn ; }
set {
this . tintSortColumn = value ;
if ( value & & this . PrimarySortColumn ! = null )
this . SelectedColumn = this . PrimarySortColumn ;
else
this . SelectedColumn = null ;
}
}
private bool tintSortColumn ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> ̬<EFBFBD> <CCAC> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks>
/// <20> <> <EFBFBD> <EFBFBD> ΪTrue<75> <65> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ״̬(ͨ<> <CDA8> <EFBFBD> Dz<EFBFBD> ȷ<EFBFBD> <C8B7> <EFBFBD> <EFBFBD> )<29> <>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> ѡ <EFBFBD> к<EFBFBD> ȡ<EFBFBD> <C8A1> ѡ <EFBFBD> <D1A1> ֮<EFBFBD> 佻<EFBFBD> 浥<EFBFBD> <E6B5A5> <EFBFBD> <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪFalseʱ<65> <CAB1> CheckStateGetter<65> Կ<EFBFBD> <D4BF> Է<EFBFBD> <D4B7> ز<EFBFBD> ȷ<EFBFBD> <C8B7> <EFBFBD> <EFBFBD>
/// </remarks>
[ Category ( "ObjectListView" ) ,
2021-01-23 15:35:30 +00:00
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> ̬<EFBFBD> <CCAC> ѡ <EFBFBD> <D1A1> " ) ,
2021-01-12 08:32:13 +00:00
DefaultValue ( false ) ]
public virtual bool TriStateCheckBoxes {
get { return triStateCheckBoxes ; }
set {
triStateCheckBoxes = value ;
if ( value & & ! this . CheckBoxes )
this . CheckBoxes = true ;
this . InitializeStateImageList ( ) ;
}
}
private bool triStateCheckBoxes ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Խ<EFBFBD> <D4BD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <CFB8> Ϣ<EFBFBD> <CFA2> ͼ<EFBFBD> <CDBC> <EFBFBD> Ҳ<EFBFBD> <D2B2> <EFBFBD> ʾ <EFBFBD> <CABE> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> á<EFBFBD>
/// </para>
/// <para>
/// <20> <> ʾ <EFBFBD> <CABE> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> õ<EFBFBD> ԭ<EFBFBD> <D4AD> <EFBFBD> ǣ<EFBFBD> <C7A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> ۹<EFBFBD> <DBB9> <EFBFBD> λ<EFBFBD> <CEBB> <EFBFBD> <EFBFBD> <EFBFBD> Σ<EFBFBD>
/// Windows msg LVM_GETTOPINDEX<45> <58> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> 0<EFBFBD> <30>
/// </para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual int TopItemIndex {
get {
if ( this . View = = View . Details & & this . IsHandleCreated )
return NativeMethods . GetTopIndex ( this ) ;
return - 1 ;
}
set {
int newTopIndex = Math . Min ( value , this . GetItemCount ( ) - 1 ) ;
if ( this . View ! = View . Details | | newTopIndex < 0 )
return ;
try {
this . TopItem = this . Items [ newTopIndex ] ;
// Setting the TopItem sometimes gives off by one errors,
// that (bizarrely) are correct on a second attempt
if ( this . TopItem ! = null & & this . TopItem . Index ! = newTopIndex )
this . TopItem = this . GetItem ( newTopIndex ) ;
}
catch ( NullReferenceException ) {
// There is a bug in the .NET code where setting the TopItem
// will sometimes throw null reference exceptions
// There is nothing we can do to get around it.
}
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƶ<EFBFBD> <C6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> ᴥ<EFBFBD> <E1B4A5> CellOver<65> ¼<EFBFBD> <C2BC> <EFBFBD>
/// Ĭ<> <C4AC> Ϊtrue<75> <65>
/// </summary>
/// <remarks>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƶ<EFBFBD> <C6B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֮ǰ<D6AE> <C7B0> <EFBFBD> ᴥ<EFBFBD> <E1B4A5> CellOver<65> ¼<EFBFBD> <C2BC> <EFBFBD> <EFBFBD> <EFBFBD> ΪHeader<65> <72> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> <EFBFBD> Ŀؼ<C4BF> <D8BC> <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> ĵ<EFBFBD> <C4B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> ó<EFBFBD> <C3B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ⣬<EFBFBD> 뽫<EFBFBD> <EBBDAB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪFalse<73> <65>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֪<EFBFBD> <D6AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> ڱ<EFBFBD> <DAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƶ<EFBFBD> <C6B6> <EFBFBD> <EFBFBD> 뽫<EFBFBD> <EBBDAB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊtrue(Ĭ<> <C4AC> ֵ)<29> <>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƶ<EFBFBD> <C6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> ᴥ<EFBFBD> <E1B4A5> CellOver<65> ¼<EFBFBD> <C2BC> <EFBFBD> " ) ,
DefaultValue ( true ) ]
public bool TriggerCellOverEventsWhenOverHeader
{
get { return triggerCellOverEventsWhenOverHeader ; }
set { triggerCellOverEventsWhenOverHeader = value ; }
}
private bool triggerCellOverEventsWhenOverHeader = true ;
/// <summary>
/// ͨ<> <CDA8> <EFBFBD> ϶<EFBFBD> <CFB6> ָ<EFBFBD> <D6B8> ߵ <EFBFBD> <DFB5> <EFBFBD> <EFBFBD> е Ĵ<D0B5> С ʱ<D0A1> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƶ<EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ո <EFBFBD> <D5B8> <EFBFBD> <EFBFBD> е Ĵ<D0B5> С <EFBFBD> <D0A1>
/// <20> <> <EFBFBD> <EFBFBD> ΪFalse<73> <65> <EFBFBD> <EFBFBD> <EFBFBD> ͷ<EFBFBD> <CDB7> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ռ <EFBFBD> <D5BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ<EFBFBD> <CEBB> <EFBFBD> <EFBFBD> <EFBFBD> ڵ<EFBFBD> <DAB5> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> <D0A1> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> ࣬<EFBFBD> ⿴<EFBFBD> <E2BFB4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֣<EFBFBD> <D6A3> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> ұ<EFBFBD> Ե<EFBFBD> <D4B5> <EFBFBD> <EFBFBD> <EFBFBD> ϶<EFBFBD> <CFB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڿռ <DABF> <D5BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <b><3E> <> <EFBFBD> <EFBFBD> Ե</b><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> ƶ<EFBFBD> <C6B6> <EFBFBD>
/// </para>
/// <para><3E> <> <EFBFBD> ǺϺ <C7BA> <CFBA> <EFBFBD> <DFBC> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ--ֻ<> ǿ<EFBFBD> <C7BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ԡ<EFBFBD>
/// </para>
/// <para>
/// <20> <> <EFBFBD> ǵ<EFBFBD> <C7B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ռ <EFBFBD> <D5BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> в<EFBFBD> <D0B2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ұߵ <D2B1> <DFB5> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> ùرո <D8B1> <D5B8> <EFBFBD> <EFBFBD> ԡ<EFBFBD> </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "ͨ<> <CDA8> <EFBFBD> ϶<EFBFBD> <CFB6> ָ<EFBFBD> <D6B8> ߵ <EFBFBD> <DFB5> <EFBFBD> <EFBFBD> е Ĵ<D0B5> С ʱ<D0A1> <CAB1> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƶ<EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ո <EFBFBD> <D5B8> <EFBFBD> <EFBFBD> е Ĵ<D0B5> С " ) ,
DefaultValue ( true ) ]
public virtual bool UpdateSpaceFillingColumnsWhenDraggingColumnDivider {
get { return updateSpaceFillingColumnsWhenDraggingColumnDivider ; }
set { updateSpaceFillingColumnsWhenDraggingColumnDivider = value ; }
}
private bool updateSpaceFillingColumnsWhenDraggingColumnDivider = true ;
/// <summary>
/// <20> <> <EFBFBD> ؼ<EFBFBD> û<EFBFBD> н<EFBFBD> <D0BD> <EFBFBD> ʱ<EFBFBD> <CAB1> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> ʲô<CAB2> <C3B4> ɫ<EFBFBD> <C9AB> Ϊѡ <CEAA> <D1A1> <EFBFBD> е ı <D0B5> <C4B1> <EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> ؼ<EFBFBD> û<EFBFBD> н<EFBFBD> <D0BD> <EFBFBD> ʱ<EFBFBD> <CAB1> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> ʲô<CAB2> <C3B4> ɫ<EFBFBD> <C9AB> Ϊѡ <CEAA> <D1A1> <EFBFBD> е ı <D0B5> <C4B1> <EFBFBD> " ) ,
DefaultValue ( typeof ( Color ) , "" ) ]
public virtual Color UnfocusedSelectedBackColor {
get { return this . unfocusedSelectedBackColor ; }
set { this . unfocusedSelectedBackColor = value ; }
}
private Color unfocusedSelectedBackColor = Color . Empty ;
/// <summary>
/// <20> <> <EFBFBD> ؼ<EFBFBD> û<EFBFBD> н<EFBFBD> <D0BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> ֵʱ<D6B5> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> е ı <D0B5> <C4B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɫ
/// </summary>
[Browsable(false)]
public virtual Color UnfocusedSelectedBackColorOrDefault {
get {
return this . UnfocusedSelectedBackColor . IsEmpty ? SystemColors . Control : this . UnfocusedSelectedBackColor ;
}
}
/// <summary>
///<2F> <> <EFBFBD> ؼ<EFBFBD> û<EFBFBD> н<EFBFBD> <D0BD> <EFBFBD> ʱ<EFBFBD> <CAB1> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> ʲô<CAB2> <C3B4> ɫ<EFBFBD> <C9AB> Ϊѡ <CEAA> <D1A1> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɫ<EFBFBD> <C9AB>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> ؼ<EFBFBD> û<EFBFBD> н<EFBFBD> <D0BD> <EFBFBD> ʱ<EFBFBD> <CAB1> Ӧ<EFBFBD> <D3A6> ʹ <EFBFBD> <CAB9> ʲô<CAB2> <C3B4> ɫ<EFBFBD> <C9AB> Ϊѡ <CEAA> <D1A1> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɫ<EFBFBD> <C9AB> " ) ,
DefaultValue ( typeof ( Color ) , "" ) ]
public virtual Color UnfocusedSelectedForeColor {
get { return this . unfocusedSelectedForeColor ; }
set { this . unfocusedSelectedForeColor = value ; }
}
private Color unfocusedSelectedForeColor = Color . Empty ;
/// <summary>
/// <20> <> <EFBFBD> ؼ<EFBFBD> û<EFBFBD> н<EFBFBD> <D0BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> ֵʱ<D6B5> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɫ
/// </summary>
[Browsable(false)]
public virtual Color UnfocusedSelectedForeColorOrDefault {
get {
return this . UnfocusedSelectedForeColor . IsEmpty ? SystemColors . ControlText : this . UnfocusedSelectedForeColor ;
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> Ƿ<EFBFBD> ÿ<EFBFBD> <C3BF> һ <EFBFBD> <D2BB> <EFBFBD> ṩ<EFBFBD> <E1B9A9> ͬ<EFBFBD> ı <EFBFBD> <C4B1> <EFBFBD> ɫ<EFBFBD> <C9AB> Ĭ<EFBFBD> <C4AC> ֵΪfalse<73> <65>
/// </summary>
/// <remarks><para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> ɫ<EFBFBD> <C9AB> AlternateRowBackColor<6F> ṩ<EFBFBD> <E1B9A9> </para>
/// <para><3E> <> .NET<45> У <EFBFBD> <D0A3> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> ڷ<EFBFBD> <DAB7> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> ģʽ <C4A3> <CABD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ܡ<EFBFBD> <DCA1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģʽ <C4A3> £<EFBFBD> <C2A3> <EFBFBD> ѡ <EFBFBD> в<EFBFBD> <D0B2> <EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> ȷ<EFBFBD> ı <EFBFBD> <C4B1> <EFBFBD> ɫ<EFBFBD> <C9AB> <EFBFBD> ơ<EFBFBD> </para></remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> Ƿ<EFBFBD> ÿ<EFBFBD> <C3BF> һ <EFBFBD> <D2BB> <EFBFBD> ṩ<EFBFBD> <E1B9A9> ͬ<EFBFBD> ı <EFBFBD> <C4B1> <EFBFBD> ɫ<EFBFBD> <C9AB> Ĭ<EFBFBD> <C4AC> ֵΪfalse<73> <65> " ) ,
DefaultValue ( false ) ]
public virtual bool UseAlternatingBackColors {
get { return useAlternatingBackColors ; }
set { useAlternatingBackColors = value ; }
}
private bool useAlternatingBackColors ;
/// <summary>
/// <20> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> Ϊ<EFBFBD> ؼ<EFBFBD> <D8BC> е <EFBFBD> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> FormatCell<6C> ¼<EFBFBD> <C2BC> <EFBFBD>
/// </summary>
/// <remarks>
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> £<EFBFBD> <C2A3> <EFBFBD> ִ<EFBFBD> е <EFBFBD> Ԫ<EFBFBD> <EFBFBD> ʽ <EFBFBD> <CABD> <EFBFBD> á<EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> ObjectListView<65> <77> <EFBFBD> <EFBFBD> Ϊÿ<CEAA> <C3BF> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <EFBFBD> Format Cell<6C> ¼<EFBFBD> <C2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ٶȻ<D9B6> <C8BB> Կ<EFBFBD> һ Щ<D2BB> <D0A9>
/// <20> <> <EFBFBD> ˣ<EFBFBD> Ĭ<EFBFBD> <C4AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> £<EFBFBD> <C2A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊÿ<CEAA> <C3BF> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ¼<EFBFBD> <C2BC> <EFBFBD>
/// </para>
/// <para>ObjectListView*ȷʵ*<2A> <> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> FormatRow<6F> ¼<EFBFBD> <C2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> п<EFBFBD> <D0BF> Ծ<EFBFBD> <D4BE> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> FormatCell<6C> ¼<EFBFBD> <C2BC> <EFBFBD>
/// </para>
/// <para>
/// <20> <> <EFBFBD> ۴<EFBFBD> <DBB4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Σ<EFBFBD> ֻ<EFBFBD> е <EFBFBD> ObjectListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <CFB8> ͼ<EFBFBD> <CDBC> ʱ<EFBFBD> Ż<EFBFBD> <C5BB> <EFBFBD> <EFBFBD> <EFBFBD> FormatCell<6C> ¼<EFBFBD> <C2BC> <EFBFBD> </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> Ϊ<EFBFBD> ؼ<EFBFBD> <D8BC> е <EFBFBD> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> FormatCell<6C> ¼<EFBFBD> " ) ,
DefaultValue ( false ) ]
public bool UseCellFormatEvents {
get { return useCellFormatEvents ; }
set { useCellFormatEvents = value ; }
}
private bool useCellFormatEvents ;
/// <summary>
/// <20> <> ѡ <EFBFBD> <D1A1> <EFBFBD> Ƿ<EFBFBD> Ӧʹ <D3A6> ÷DZ<C3B7> ǰ<D7BC> <C7B0> ɫ<EFBFBD> ͱ<EFBFBD> <CDB1> <EFBFBD> ɫ<EFBFBD> <C9AB> <EFBFBD> ƣ<EFBFBD>
/// </summary>
/// <remarks>V2.9<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ѡ <EFBFBD> <D1A1> <EFBFBD> Ƿ<EFBFBD> Ӧʹ <D3A6> ÷DZ<C3B7> ǰ<D7BC> <C7B0> ɫ<EFBFBD> ͱ<EFBFBD> <CDB1> <EFBFBD> ɫ<EFBFBD> <C9AB> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( false ) ]
public bool UseCustomSelectionColors {
get { return false ; }
// ReSharper disable once ValueParameterNotUsed
set { }
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ô<EFBFBD> ObjectListView<65> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> Vista<74> <61> Դ<EFBFBD> <D4B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> ơ<EFBFBD>
/// </summary>
/// <remarks>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȱ<EFBFBD> ݣ<EFBFBD>
/// <list type="bullet">
/// <item><description><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Vista<74> <61> <EFBFBD> <EFBFBD> <EFBFBD> ߰汾</description></item>
/// <item><description><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> ܺܺõ<DCBA> <C3B5> <EFBFBD> AlternateRowBackColors<72> <73> <EFBFBD> <EFBFBD> ʹ <EFBFBD> á<EFBFBD> </description></item>
/// <item><description><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> ܺܺõ<DCBA> <C3B5> <EFBFBD> HotItemStyles<65> <73> <EFBFBD> <EFBFBD> ʹ <EFBFBD> á<EFBFBD> </description></item>
/// <item><description><3E> <> <EFBFBD> <EFBFBD> FullRowSelectΪfalse<73> <65> <EFBFBD> ⿴<EFBFBD> <E2BFB4> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ɵ<EFBFBD> <C9B5> </description></item>
/// <item><description><3E> <> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <DFBB> Ƶ<EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> (<28> <> Ϊ<EFBFBD> <CEAA> <EFBFBD> е Ļ<D0B5> <C4BB> ƶ<EFBFBD> <C6B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ⱦ<EFBFBD> <C8BE> <EFBFBD> <EFBFBD> <EFBFBD> ɵ<EFBFBD> )<29> <>
/// <20> <> <EFBFBD> ˣ<EFBFBD> <CBA3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> TreeListViewһ <77> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> ǡ<EFBFBD> <C7A1> <EFBFBD> <EFBFBD> 롱<EFBFBD> <EBA1B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <DFBB> Ƶġ<C6B5> <C4A1> <EFBFBD> <EFBFBD> <EFBFBD> Ȼ<EFBFBD> <C8BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ч<EFBFBD> <D0A7> </description></item>
/// </list>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Vista/Win7<6E> <37> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ȩ<EFBFBD> ޡ<EFBFBD> <DEA1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ø<EFBFBD> <C3B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 飬<EFBFBD> 벻Ҫ<EBB2BB> <D2AA> Թ<EFBFBD> <D4B9>
/// </para>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪTrueʱ<65> <CAB1> ObjectListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ġ<EFBFBD>
/// <20> ⽫<EFBFBD> <E2BDAB> <EFBFBD> <EFBFBD> ObjectListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ư<EFBFBD> <C6AF> <EFBFBD> Ļ<EFBFBD> <C4BB> ڻ<EFBFBD> ͼ<EFBFBD> Ĺ<EFBFBD> <C4B9> ܡ<EFBFBD>
/// </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ô<EFBFBD> ObjectListView<65> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> Vista<74> <61> Դ<EFBFBD> <D4B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( false ) ]
public bool UseExplorerTheme {
get { return useExplorerTheme ; }
set {
useExplorerTheme = value ;
if ( this . Created )
NativeMethods . SetWindowTheme ( this . Handle , value ? "explorer" : "" , null ) ;
this . OwnerDraw = ! value ;
}
}
private bool useExplorerTheme ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ɸѡ
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> ɸѡ " ) ,
DefaultValue ( false ) ]
virtual public bool UseFiltering {
get { return useFiltering ; }
set {
if ( useFiltering = = value )
return ;
useFiltering = value ;
this . UpdateFiltering ( ) ;
}
}
private bool useFiltering ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ָʾ <D6B8> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е ı <D0B5> <C4B1> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> Ա<EFBFBD> <D4B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊtrue<75> <65> HeaderUsesThemes<65> <73> <EFBFBD> Զ<EFBFBD> <D4B6> <EFBFBD> <EFBFBD> <EFBFBD> Ϊfalse<73> <65> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> ֻ<EFBFBD> <D6BB> <EFBFBD> ڲ<EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1> ָʾ <D6B8> <CABE> <EFBFBD> <EFBFBD> </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ָʾ <D6B8> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е ı <D0B5> <C4B1> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> Ա<EFBFBD> <D4B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( false ) ]
virtual public bool UseFilterIndicator {
get { return useFilterIndicator ; }
set {
if ( this . useFilterIndicator = = value )
return ;
useFilterIndicator = value ;
if ( this . useFilterIndicator )
this . HeaderUsesThemes = false ;
this . Invalidate ( ) ;
}
}
private bool useFilterIndicator ;
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ·<EFBFBD> <C2B7> Ŀؼ<C4BF> (<28> <> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ť)<29> Ƿ<EFBFBD> Ӧ<EFBFBD> ñ<EFBFBD> <C3B1> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> Hot<6F> <74>
/// </summary>
/// <remarks>
/// <para><3E> <> <EFBFBD> <EFBFBD> ΪFalse<73> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͣ<EFBFBD> ڿؼ<DABF> <D8BC> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> ؼ<EFBFBD> <D8BC> Ļ<EFBFBD> <C4BB> Ʒ <EFBFBD> ʽ <EFBFBD> <CABD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC> </para>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> ΪFalse<73> <65> <EFBFBD> <EFBFBD> UseHotItem<65> <6D> UseHyperLinksΪFalse<73> <65> <EFBFBD> <EFBFBD> ObjectListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƶ<EFBFBD> <C6B6> <EFBFBD> ijЩ<C4B3> <D0A9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƶ<EFBFBD> <C6B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> CPU<50> <55>
/// </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> <EFBFBD> <EFBFBD> ·<EFBFBD> <C2B7> Ŀؼ<C4BF> (<28> <> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ť)<29> Ƿ<EFBFBD> Ӧ<EFBFBD> ñ<EFBFBD> <C3B1> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> Hot<6F> <74> " ) ,
DefaultValue ( true ) ]
public bool UseHotControls {
get { return this . useHotControls ; }
set { this . useHotControls = value ; }
}
private bool useHotControls = true ;
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> µ<EFBFBD> <C2B5> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> ⷽʽ <E2B7BD> <CABD> <EFBFBD> ø<EFBFBD> ʽ <EFBFBD> <CABD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> <EFBFBD> <EFBFBD> <EFBFBD> µ<EFBFBD> <C2B5> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> ⷽʽ <E2B7BD> <CABD> <EFBFBD> ø<EFBFBD> ʽ " ) ,
DefaultValue ( false ) ]
public bool UseHotItem {
get { return this . useHotItem ; }
set {
this . useHotItem = value ;
if ( value )
this . AddOverlay ( this . HotItemStyleOrDefault . Overlay ) ;
else
this . RemoveOverlay ( this . HotItemStyleOrDefault . Overlay ) ;
}
}
private bool useHotItem ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ô<EFBFBD> <C3B4> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> ڵ<EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> ӡ<EFBFBD>
/// </summary>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> ô<EFBFBD> <C3B4> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> Ƿ<EFBFBD> Ӧ<EFBFBD> ڵ<EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( false ) ]
public bool UseHyperlinks {
get { return this . useHyperlinks ; }
set {
this . useHyperlinks = value ;
if ( value & & this . HyperlinkStyle = = null )
this . HyperlinkStyle = new HyperlinkStyle ( ) ;
}
}
private bool useHyperlinks ;
/// <summary>
/// <20> ˿ؼ<CBBF> <D8BC> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> (Overlays)
/// </summary>
/// <remarks><3E> <> <EFBFBD> <EFBFBD> (Overlays)<29> <> Ĭ<EFBFBD> <C4AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> õģ<C3B5> ֻ<EFBFBD> <D6BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> á<EFBFBD> </remarks>
[ Category ( "ObjectListView" ) ,
2021-01-23 15:35:30 +00:00
Description ( "<22> ˿ؼ<CBBF> <D8BC> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> (Overlays)" ) ,
2021-01-12 08:32:13 +00:00
DefaultValue ( true ) ]
public bool UseOverlays {
get { return this . useOverlays ; }
set { this . useOverlays = value ; }
}
private bool useOverlays = true ;
/// <summary>
/// <20> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> ˿ؼ<CBBF> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD>
/// </summary>
/// <remarks><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪTrue<75> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> ÿؼ<C3BF> <D8BC> ṩһ <E1B9A9> <D2BB> SmallImageList(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> һ <EFBFBD> <D2BB> SmallImageList)<29> <>
/// <20> <> <EFBFBD> ⣬<EFBFBD> <E2A3AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> <C4A3> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> »<EFBFBD> <C2BB> Ƹ<EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> ˿ؼ<CBBF> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( false ) ]
public bool UseSubItemCheckBoxes {
get { return this . useSubItemCheckBoxes ; }
set {
this . useSubItemCheckBoxes = value ;
if ( value )
this . SetupSubItemCheckBoxes ( ) ;
}
}
private bool useSubItemCheckBoxes ;
/// <summary>
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ObjectListView<65> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Vista<74> İ<EFBFBD> <EFBFBD> <CDB8> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> ơ<EFBFBD>
/// </summary>
/// <remarks>
/// <para>
/// <20> <> UseExplorerTheme<6D> <65> ͬ<EFBFBD> <CDAC> <EFBFBD> ǣ<EFBFBD> <C7A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Vista<74> ķ<EFBFBD> <C4B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> XP<58> <50> <EFBFBD> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> Ҽ<EFBFBD> <D2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> Ҳ<EFBFBD> <D2B2> <EFBFBD> <EFBFBD> <EFBFBD> ڷ<EFBFBD> <DAB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD>
/// </para>
/// <para>
///<2F> ⽫<EFBFBD> 滻<EFBFBD> κ<EFBFBD> <CEBA> Ѱ<EFBFBD> װ<EFBFBD> <D7B0> SelectedRowDecory<72> <79>
/// </para>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϲ <EFBFBD> <CFB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɫ<EFBFBD> <C9AB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Դ<EFBFBD> <D4B4> <EFBFBD> <EFBFBD> ԣ<EFBFBD>
/// ֻ<> 贴<EFBFBD> <E8B4B4> <EFBFBD> <EFBFBD> <EFBFBD> Լ<EFBFBD> <D4BC> <EFBFBD> RowBorderDecory<72> <79> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SelectedRowDecory<72> <79>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ObjectListView<65> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Vista<74> İ<EFBFBD> <EFBFBD> <CDB8> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
DefaultValue ( false ) ]
public bool UseTranslucentSelection {
get { return useTranslucentSelection ; }
set {
useTranslucentSelection = value ;
if ( value ) {
RowBorderDecoration rbd = new RowBorderDecoration ( ) ;
rbd . BorderPen = new Pen ( Color . FromArgb ( 154 , 223 , 251 ) ) ;
rbd . FillBrush = new SolidBrush ( Color . FromArgb ( 48 , 163 , 217 , 225 ) ) ;
rbd . BoundsPadding = new Size ( 0 , 0 ) ;
rbd . CornerRounding = 6.0f ;
this . SelectedRowDecoration = rbd ;
} else
this . SelectedRowDecoration = null ;
}
}
private bool useTranslucentSelection ;
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ObjectListView<65> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Vista<74> İ<EFBFBD> <EFBFBD> <CDB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͻ<EFBFBD> <CDBB> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> ơ<EFBFBD>
/// </summary>
/// <remarks>
/// <para>
/// <20> <> <EFBFBD> ô<EFBFBD> <C3B4> <EFBFBD> 滻<EFBFBD> κ<EFBFBD> <CEBA> Ѱ<EFBFBD> װ<EFBFBD> <D7B0> HotItemStyle<6C> <65>
/// </para>
/// <para>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϲ <EFBFBD> <CFB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀʹ <C4BF> õ<EFBFBD> <C3B5> <EFBFBD> ɫ<EFBFBD> <C9AB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Դ<EFBFBD> <D4B4> <EFBFBD> <EFBFBD> ԣ<EFBFBD>
/// ֻ<> 贴<EFBFBD> <E8B4B4> <EFBFBD> <EFBFBD> <EFBFBD> Լ<EFBFBD> <D4BC> <EFBFBD> HotItemStyle<6C> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> HotItemStyle<6C> <65> <EFBFBD> ԣ<EFBFBD> <D4A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// </para>
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ObjectListView<65> Ƿ<EFBFBD> <C7B7> <EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Vista<74> İ<EFBFBD> <EFBFBD> <CDB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͻ<EFBFBD> <CDBB> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> ơ<EFBFBD> " ) ,
DefaultValue ( false ) ]
public bool UseTranslucentHotItem {
get { return useTranslucentHotItem ; }
set {
useTranslucentHotItem = value ;
if ( value ) {
RowBorderDecoration rbd = new RowBorderDecoration ( ) ;
rbd . BorderPen = new Pen ( Color . FromArgb ( 154 , 223 , 251 ) ) ;
rbd . BoundsPadding = new Size ( 0 , 0 ) ;
rbd . CornerRounding = 6.0f ;
rbd . FillGradientFrom = Color . FromArgb ( 0 , 255 , 255 , 255 ) ;
rbd . FillGradientTo = Color . FromArgb ( 64 , 183 , 237 , 240 ) ;
HotItemStyle his = new HotItemStyle ( ) ;
his . Decoration = rbd ;
this . HotItemStyle = his ;
} else
this . HotItemStyle = null ;
this . UseHotItem = value ;
}
}
private bool useTranslucentHotItem ;
/// <summary>
/// <20> <> ȡ/<2F> <> <EFBFBD> ô<EFBFBD> <C3B4> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʹ <EFBFBD> õ<EFBFBD> <C3B5> <EFBFBD> ͼ<EFBFBD> <CDBC> ʽ
/// </summary>
/// <remarks><3E> л<EFBFBD> <D0BB> <EFBFBD> ƽ <EFBFBD> <C6BD> (Tile)<29> <> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <CFB8> Ϣ(Details)<29> <> ͼ<EFBFBD> ᰲװ<E1B0B2> ʺϸ<CABA> <CFB8> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> С <EFBFBD> <D0A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǣ<EFBFBD> <C7A3> <EFBFBD> ƽ <EFBFBD> <C6BD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> У <EFBFBD> ÿ<EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> ʾ Ϊһ <CEAA> <D2BB> <EFBFBD> <EFBFBD> Ϣ<EFBFBD> <CFA2> </remarks>
[ Category ( "Appearance" ) ,
Description ( "<22> <> ȡ/<2F> <> <EFBFBD> ô<EFBFBD> <C3B4> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʹ <EFBFBD> õ<EFBFBD> <C3B5> <EFBFBD> ͼ<EFBFBD> <CDBC> ʽ " ) ,
DefaultValue ( null ) ]
new public View View
{
get { return base . View ; }
set {
if ( base . View = = value )
return ;
if ( this . Frozen ) {
base . View = value ;
this . SetupBaseImageList ( ) ;
} else {
this . Freeze ( ) ;
if ( value = = View . Tile )
this . CalculateReasonableTileSize ( ) ;
base . View = value ;
this . SetupBaseImageList ( ) ;
this . Unfreeze ( ) ;
}
}
}
#endregion
#region Callbacks
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> ί<EFBFBD> н<EFBFBD> <D0BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ļ<EFBFBD> <C4BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> ȡ<EFBFBD> <C8A1>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-09-12 06:54:13 +00:00
/// <remarks><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Զ<EFBFBD> <D4B6> <EFBFBD> 뵣<EFBFBD> IJ<EFBFBD> ȷ<EFBFBD> <C8B7> ״̬(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> ൱<EFBFBD> <E0B5B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )<29> <> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ô<EFBFBD> ѡ <EFBFBD>
2021-01-12 08:32:13 +00:00
/// <para>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> CheckStateGetter<65> <72> <EFBFBD> Եı <D4B5> <C4B1> ݰ<EFBFBD> װ<EFBFBD> <D7B0>
2021-01-12 08:32:13 +00:00
/// </para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual BooleanCheckStateGetterDelegate BooleanCheckStateGetter {
set {
if ( value = = null )
this . CheckStateGetter = null ;
else
this . CheckStateGetter = delegate ( Object x ) {
return value ( x ) ? CheckState . Checked : CheckState . Unchecked ;
} ;
}
}
/// <summary>
/// This delegate sets the checkedness of an object as a boolean only. It must return
/// true or false indicating if the object was checked or not.
/// </summary>
/// <remarks>Use this if you never want to worry about the
/// Indeterminate state (which is fairly common).
/// <para>
/// This is a convenience wrapper around the CheckStatePutter property.
/// </para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual BooleanCheckStatePutterDelegate BooleanCheckStatePutter {
set {
if ( value = = null )
this . CheckStatePutter = null ;
else
this . CheckStatePutter = delegate ( Object x , CheckState state ) {
bool isChecked = ( state = = CheckState . Checked ) ;
return value ( x , isChecked ) ? CheckState . Checked : CheckState . Unchecked ;
} ;
}
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> Ƿ<EFBFBD> <C7B7> ܹ<EFBFBD> <DCB9> <EFBFBD> ʾ <EFBFBD> <CABE>
2021-01-12 08:32:13 +00:00
/// </summary>
[Browsable(false)]
public virtual bool CanShowGroups {
get {
return true ;
}
}
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ObjectListView<65> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Application.Idle<6C> ¼<EFBFBD> <C2BC> <EFBFBD>
/// </summary>
/// <remarks><3E> <> ijЩ<C4B3> <D0A9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> (<28> <> <EFBFBD> 磬<EFBFBD> <E7A3AC> VisualStudio<69> <6F> Office<63> <65> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> չ<EFBFBD> <D5B9> <EFBFBD> <EFBFBD> ʱ)<29> <> <EFBFBD> Ӳ<EFBFBD> <D3B2> <EFBFBD> <EFBFBD> <EFBFBD> Application.Idle<6C> ¼<EFBFBD> <C2BC> <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Idle<6C> ¼<EFBFBD> <C2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪFalse<73> <65> ObjectListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Щ<EFBFBD> ¼<EFBFBD> <C2BC> <EFBFBD>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual bool CanUseApplicationIdle {
get { return this . canUseApplicationIdle ; }
set { this . canUseApplicationIdle = value ; }
}
private bool canUseApplicationIdle = true ;
/// <summary>
/// This delegate fetches the renderer for a particular cell.
/// </summary>
/// <remarks>
/// <para>
/// If this returns null (or is not installed), the renderer for the column will be used.
/// If the column renderer is null, then <seealso cref="DefaultRenderer"/> will be used.
/// </para>
/// <para>
/// This is called every time any cell is drawn. It must be efficient!
/// </para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual CellRendererGetterDelegate CellRendererGetter
{
get { return this . cellRendererGetter ; }
set { this . cellRendererGetter = value ; }
}
private CellRendererGetterDelegate cellRendererGetter ;
/// <summary>
/// This delegate is called when the list wants to show a tooltip for a particular cell.
/// The delegate should return the text to display, or null to use the default behavior
/// (which is to show the full text of truncated cell values).
/// </summary>
/// <remarks>
/// Displaying the full text of truncated cell values only work for FullRowSelect listviews.
/// This is MS's behavior, not mine. Don't complain to me :)
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual CellToolTipGetterDelegate CellToolTipGetter {
get { return cellToolTipGetter ; }
set { cellToolTipGetter = value ; }
}
private CellToolTipGetterDelegate cellToolTipGetter ;
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> ѡ <EFBFBD> <D1A1> ģ<EFBFBD> ͵<EFBFBD> <CDB5> <EFBFBD> <EFBFBD> <EFBFBD> (<28> <> <EFBFBD> ֶ<EFBFBD> )<29> <> <EFBFBD> <EFBFBD> <EFBFBD> ơ<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>
2021-09-12 06:54:13 +00:00
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǿ<EFBFBD> <C7BF> ĵġ<C4B5> <C4A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> bool(<28> <> bool<6F> <6C> )<29> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͡<EFBFBD> <CDA1> <EFBFBD> <EFBFBD> <EFBFBD> TriStateCheckBooksΪ<73> <CEAA> )<29> <> </para>
/// <para><3E> <> <EFBFBD> ô<EFBFBD> <C3B4> <EFBFBD> <EFBFBD> Խ<EFBFBD> <D4BD> 滻<EFBFBD> κ<EFBFBD> <CEBA> Ѱ<EFBFBD> װ<EFBFBD> <D7B0> CheckStateGetter<65> <72> CheckStatePutter<65> <72>
/// <20> ෴<EFBFBD> <E0B7B4> <EFBFBD> Ժ<EFBFBD> <D4BA> <EFBFBD> <EFBFBD> <EFBFBD> CheckStateGetter<65> <72> CheckStatePutter<65> <72> <EFBFBD> Խ<EFBFBD> <D4BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڴ<EFBFBD> <DAB4> <EFBFBD> <EFBFBD> Ե<EFBFBD> <D4B5> <EFBFBD> Ϊ<EFBFBD> <CEAA> </para>
2021-01-12 08:32:13 +00:00
/// </remarks>
[ Category ( "ObjectListView" ) ,
2021-09-12 06:54:13 +00:00
Description ( "<22> <> <EFBFBD> <EFBFBD> ģ<EFBFBD> ͵ġ<CDB5> <C4A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ԡ<EFBFBD> <D4A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ի<EFBFBD> <D4BB> ֶε<D6B6> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> " ) ,
2021-01-12 08:32:13 +00:00
DefaultValue ( null ) ]
public virtual string CheckedAspectName {
get { return checkedAspectName ; }
set {
checkedAspectName = value ;
if ( String . IsNullOrEmpty ( checkedAspectName ) ) {
this . checkedAspectMunger = null ;
this . CheckStateGetter = null ;
this . CheckStatePutter = null ;
} else {
this . checkedAspectMunger = new Munger ( checkedAspectName ) ;
this . CheckStateGetter = delegate ( Object modelObject ) {
bool? result = this . checkedAspectMunger . GetValue ( modelObject ) as bool? ;
if ( result . HasValue )
return result . Value ? CheckState . Checked : CheckState . Unchecked ;
return this . TriStateCheckBoxes ? CheckState . Indeterminate : CheckState . Unchecked ;
} ;
this . CheckStatePutter = delegate ( Object modelObject , CheckState newValue ) {
if ( this . TriStateCheckBoxes & & newValue = = CheckState . Indeterminate )
this . checkedAspectMunger . PutValue ( modelObject , null ) ;
else
this . checkedAspectMunger . PutValue ( modelObject , newValue = = CheckState . Checked ) ;
return this . CheckStateGetter ( modelObject ) ;
} ;
}
}
}
private string checkedAspectName ;
private Munger checkedAspectMunger ;
/// <summary>
2021-09-12 06:54:13 +00:00
/// ֻҪObjectListView<65> <77> Ҫ֪<D2AA> <D6AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е ļ<D0B5> <C4BC> <EFBFBD> ״̬<D7B4> <CCAC> <EFBFBD> ͻ<EFBFBD> <CDBB> <EFBFBD> <EFBFBD> ô<EFBFBD> ί<EFBFBD> С <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>
/// <para>.NET has no support for indeterminate values, but as of v2.0, this class allows
/// indeterminate values.</para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual CheckStateGetterDelegate CheckStateGetter {
get { return checkStateGetter ; }
set { checkStateGetter = value ; }
}
private CheckStateGetterDelegate checkStateGetter ;
/// <summary>
/// This delegate will be called whenever the user tries to change the check state of a row.
/// The delegate should return the state that was actually set, which may be different
/// to the state given.
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual CheckStatePutterDelegate CheckStatePutter {
get { return checkStatePutter ; }
set { checkStatePutter = value ; }
}
private CheckStatePutterDelegate checkStatePutter ;
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> ί<EFBFBD> п<EFBFBD> <D0BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Զ<EFBFBD> <D4B6> 巽ʽ <E5B7BD> Ա<EFBFBD> <D4B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>
/// <para>
2021-09-12 06:54:13 +00:00
///ί<> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> ObjectListView<65> ϰ<EFBFBD> װListViewItemSorter<65> <72>
///<2F> <> װItemSorter<65> <72> ִ<EFBFBD> ж<EFBFBD> ListViewItems<6D> <73> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʵ<EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD>
///<2F> й<EFBFBD> ItemSorter<65> <72> <EFBFBD> <EFBFBD> ִ<EFBFBD> е IJ<D0B5> <C4B2> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> μ<EFBFBD> <CEBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ColumnCompeller<65> <72>
2021-01-12 08:32:13 +00:00
/// </para>
/// <para>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> VirtualObjectListView<65> ϰ<EFBFBD> װCustomSorter<65> <72> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> дIVirtualListDataSource<63> <65> SortObjects()<29> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual SortDelegate CustomSorter {
get { return customSorter ; }
set { customSorter = value ; }
}
private SortDelegate customSorter ;
/// <summary>
/// This delegate is called when the list wants to show a tooltip for a particular header.
/// The delegate should return the text to display, or null to use the default behavior
/// (which is to not show any tooltip).
/// </summary>
/// <remarks>
/// Installing a HeaderToolTipGetter takes precedence over any text in OLVColumn.ToolTipText.
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual HeaderToolTipGetterDelegate HeaderToolTipGetter {
get { return headerToolTipGetter ; }
set { headerToolTipGetter = value ; }
}
private HeaderToolTipGetterDelegate headerToolTipGetter ;
/// <summary>
/// This delegate can be used to format a OLVListItem before it is added to the control.
/// </summary>
/// <remarks>
/// <para>The model object for the row can be found through the RowObject property of the OLVListItem object.</para>
/// <para>All subitems normally have the same style as list item, so setting the forecolor on one
/// subitem changes the forecolor of all subitems.
/// To allow subitems to have different attributes, do this:
/// <code>myListViewItem.UseItemStyleForSubItems = false;</code>.
/// </para>
/// <para>If UseAlternatingBackColors is true, the backcolor of the listitem will be calculated
/// by the control and cannot be controlled by the RowFormatter delegate.
/// In general, trying to use a RowFormatter
/// when UseAlternatingBackColors is true does not work well.</para>
/// <para>As it says in the summary, this is called <b>before</b> the item is added to the control.
/// Many properties of the OLVListItem itself are not available at that point, including:
/// Index, Selected, Focused, Bounds, Checked, DisplayIndex.</para>
/// </remarks>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual RowFormatterDelegate RowFormatter {
get { return rowFormatter ; }
set { rowFormatter = value ; }
}
private RowFormatterDelegate rowFormatter ;
#endregion
#region List commands
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ӵ<EFBFBD> <D3B5> ˿ؼ<CBBF> <D8BC> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-09-12 06:54:13 +00:00
/// <param name="modelObject">Ҫ<> <D2AA> ʾ <EFBFBD> <CABE> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> </param>
2021-01-12 08:32:13 +00:00
/// <remarks>See AddObjects() for more details</remarks>
public virtual void AddObject ( object modelObject ) {
if ( this . InvokeRequired )
this . Invoke ( ( MethodInvoker ) delegate ( ) { this . AddObject ( modelObject ) ; } ) ;
else
this . AddObjects ( new object [ ] { modelObject } ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <F3BCAFBA> <EFBFBD> <EFBFBD> ӵ<EFBFBD> <D3B5> ˿ؼ<CBBF> <D8BC> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-09-12 06:54:13 +00:00
/// <param name="modelObjects">Ҫ<> <D2AA> ʾ <EFBFBD> <CABE> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> </param>
2021-01-12 08:32:13 +00:00
/// <remarks>
2021-09-12 06:54:13 +00:00
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڻ״̬(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> PrimarySortColumn<6D> <6E> Ϊ<EFBFBD> <CEAA> )<29> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ӵĶ<D3B5> <C4B6> <EFBFBD> <F3BDABB3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȷ<EFBFBD> <C8B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ<EFBFBD> á<EFBFBD> <C3A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǽ<EFBFBD> <C7BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ĩβ<C4A9> <CEB2> </para>
/// <para><3E> <> ִ<EFBFBD> <D6B4> <EFBFBD> κμ<CEBA> <CEBC> <EFBFBD> <EFBFBD> Բ鿴<D4B2> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> κζ<CEBA> <CEB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ListView<65> С <EFBFBD> </para>
/// <para><3E> ն<EFBFBD> <D5B6> <EFBFBD> <F3BDABB1> <EFBFBD> Ĭ<EFBFBD> <C4AC> <EFBFBD> ԡ<EFBFBD> </para>
2021-01-12 08:32:13 +00:00
/// </remarks>
public virtual void AddObjects ( ICollection modelObjects ) {
if ( this . InvokeRequired ) {
this . Invoke ( ( MethodInvoker ) delegate ( ) { this . AddObjects ( modelObjects ) ; } ) ;
return ;
}
this . InsertObjects ( ObjectListView . EnumerableCount ( this . Objects ) , modelObjects ) ;
this . Sort ( this . PrimarySortColumn , this . PrimarySortOrder ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> е Ĵ<D0B5> С <EFBFBD> <D0A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ҳü<D2B3> <C3BC> <EFBFBD> Ⱥ<EFBFBD> <C8BA> <EFBFBD> <EFBFBD> ݵ<EFBFBD> <DDB5> <EFBFBD> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5>
2021-01-12 08:32:13 +00:00
/// </summary>
public virtual void AutoResizeColumns ( ) {
foreach ( OLVColumn c in this . Columns ) {
this . AutoResizeColumn ( c . Index , ColumnHeaderAutoResizeStyle . HeaderSize ) ;
}
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> κ<EFBFBD> <CEBA> Զ<EFBFBD> <D4B6> <EFBFBD> ʼ <EFBFBD> <CABC> <EFBFBD> <EFBFBD> <EFBFBD> п<EFBFBD> (<28> <> <EFBFBD> <EFBFBD> Ϊ0<CEAA> <30> -1<> <31> <EFBFBD> н<EFBFBD> <D0BD> ֱ<EFBFBD> <D6B1> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> <EFBFBD> ݻ<EFBFBD> <DDBB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> )<29> <>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>
2021-09-12 06:54:13 +00:00
///<2F> <> Ȼ<EFBFBD> <C8BB> <EFBFBD> <EFBFBD> ֻ<EFBFBD> <D6BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> Ρ <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> п<EFBFBD> <D0BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> ֵ(<28> <> <EFBFBD> <EFBFBD> 0<EFBFBD> <30> -1)<29> <> <EFBFBD> <EFBFBD> <EFBFBD> ˵ڶ<CBB5> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> ִ<EFBFBD> <D6B4> <EFBFBD> κβ<CEBA> <CEB2> <EFBFBD> <EFBFBD> <EFBFBD>
///<2F> <> Ҫǿ<D2AA> <C7BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> и<EFBFBD> <D0B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> <D0A1> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <CAB9> <see cref="AutoResizeColumns()"/> <20> <>
2021-01-12 08:32:13 +00:00
/// </remarks>
public virtual void AutoSizeColumns ( ) {
// If we are supposed to resize to content, but if there is no content,
// resize to the header size instead.
ColumnHeaderAutoResizeStyle resizeToContentStyle = this . GetItemCount ( ) = = 0 ?
ColumnHeaderAutoResizeStyle . HeaderSize :
ColumnHeaderAutoResizeStyle . ColumnContent ;
foreach ( ColumnHeader column in this . Columns ) {
switch ( column . Width ) {
case 0 :
this . AutoResizeColumn ( column . Index , resizeToContentStyle ) ;
break ;
case - 1 :
this . AutoResizeColumn ( column . Index , ColumnHeaderAutoResizeStyle . HeaderSize ) ;
break ;
}
}
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> л<EFBFBD> <D0BB> <EFBFBD> һ <EFBFBD> <D2BB> (<28> <> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )<29> <> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ֯<EFBFBD> <D6AF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
public virtual void BuildGroups ( ) {
this . BuildGroups ( this . PrimarySortColumn , this . PrimarySortOrder = = SortOrder . None ? SortOrder . Ascending : this . PrimarySortOrder ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> ݸ<EFBFBD> <DDB8> <EFBFBD> <EFBFBD> н<EFBFBD> <D0BD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ֯<EFBFBD> <D6AF> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>
/// <para>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> AlwaysGroupByColumn<6D> <6E> <EFBFBD> Բ<EFBFBD> ΪNull<6C> <6C> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <EFBFBD> <EEBDAB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֯<EFBFBD> <D6AF> <EFBFBD> <EFBFBD> <EFBFBD> ҽ <EFBFBD> <D2BD> <EFBFBD> <EFBFBD> ԡ<EFBFBD> Column<6D> <6E> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </para>
2021-09-12 06:54:13 +00:00
/// <para><3E> ˷<EFBFBD> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ¼<EFBFBD> <C2BC> <EFBFBD> BeforeSorting<6E> <67> AfterSorting<6E> <67> </para>
2021-01-12 08:32:13 +00:00
/// </remarks>
2021-09-12 06:54:13 +00:00
/// <param name="column"><3E> <> ֵӦ<D6B5> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> </param>
2021-01-12 08:32:13 +00:00
/// <param name="order"></param>
public virtual void BuildGroups ( OLVColumn column , SortOrder order ) {
// Sanity
if ( this . GetItemCount ( ) = = 0 | | this . Columns . Count = = 0 )
return ;
BeforeSortingEventArgs args = this . BuildBeforeSortingEventArgs ( column , order ) ;
this . OnBeforeSorting ( args ) ;
if ( args . Canceled )
return ;
this . BuildGroups ( args . ColumnToGroupBy , args . GroupByOrder ,
args . ColumnToSort , args . SortOrder , args . SecondaryColumnToSort , args . SecondarySortOrder ) ;
this . OnAfterSorting ( new AfterSortingEventArgs ( args ) ) ;
}
private BeforeSortingEventArgs BuildBeforeSortingEventArgs ( OLVColumn column , SortOrder order ) {
OLVColumn groupBy = this . AlwaysGroupByColumn ? ? column ? ? this . GetColumn ( 0 ) ;
SortOrder groupByOrder = this . AlwaysGroupBySortOrder ;
if ( order = = SortOrder . None ) {
order = this . Sorting ;
if ( order = = SortOrder . None )
order = SortOrder . Ascending ;
}
if ( groupByOrder = = SortOrder . None )
groupByOrder = order ;
BeforeSortingEventArgs args = new BeforeSortingEventArgs (
groupBy , groupByOrder ,
column , order ,
this . SecondarySortColumn ? ? this . GetColumn ( 0 ) ,
this . SecondarySortOrder = = SortOrder . None ? order : this . SecondarySortOrder ) ;
if ( column ! = null )
args . Canceled = ! column . Sortable ;
return args ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> ݸ<EFBFBD> <DDB8> <EFBFBD> <EFBFBD> н<EFBFBD> <D0BD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ֯<EFBFBD> <D6AF> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-09-12 06:54:13 +00:00
/// <param name="groupByColumn"><3E> <> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> һ <EFBFBD> н<EFBFBD> <D0BD> з<EFBFBD> <D0B7> <EFBFBD> </param>
/// <param name="groupByOrder"><3E> 齫ʹ <E9BDAB> <CAB9> ʲô˳<C3B4> <CBB3> </param>
/// <param name="column"><3E> <> ֵӦ<D6B5> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> <D0A1> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> </param>
/// <param name="order"><3E> <> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ˳<EFBFBD> <CBB3> </param>
/// <param name="secondaryColumn"><3E> <> <EFBFBD> <EFBFBD> column<6D> <6E> <EFBFBD> е <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ô<EFBFBD> <C3B4> <EFBFBD> <EFBFBD> ṩ<EFBFBD> <E1B9A9> ֵ</param>
/// <param name="secondaryOrder"><3E> μ<EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> </param>
/// <remarks><3E> ˷<EFBFBD> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ᴥ<EFBFBD> <E1B4A5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ¼<EFBFBD> <C2BC> <EFBFBD> ʹ <EFBFBD> <CAB9> BuildGroups()ִ<> д˲<D0B4> <CBB2> <EFBFBD> </remarks>
2021-01-12 08:32:13 +00:00
public virtual void BuildGroups ( OLVColumn groupByColumn , SortOrder groupByOrder ,
OLVColumn column , SortOrder order , OLVColumn secondaryColumn , SortOrder secondaryOrder ) {
// Sanity checks
if ( groupByColumn = = null )
return ;
// Getting the Count forces any internal cache of the ListView to be flushed. Without
// this, iterating over the Items will not work correctly if the ListView handle
// has not yet been created.
#pragma warning disable 168
// ReSharper disable once UnusedVariable
int dummy = this . Items . Count ;
#pragma warning restore 168
// Collect all the information that governs the creation of groups
GroupingParameters parms = this . CollectGroupingParameters ( groupByColumn , groupByOrder ,
column , order , secondaryColumn , secondaryOrder ) ;
// Trigger an event to let the world create groups if they want
CreateGroupsEventArgs args = new CreateGroupsEventArgs ( parms ) ;
if ( parms . GroupByColumn ! = null )
args . Canceled = ! parms . GroupByColumn . Groupable ;
this . OnBeforeCreatingGroups ( args ) ;
if ( args . Canceled )
return ;
// If the event didn't create them for us, use our default strategy
if ( args . Groups = = null )
args . Groups = this . MakeGroups ( parms ) ;
// Give the world a chance to munge the groups before they are created
this . OnAboutToCreateGroups ( args ) ;
if ( args . Canceled )
return ;
// Create the groups now
this . OLVGroups = args . Groups ;
this . CreateGroups ( args . Groups ) ;
// Tell the world that new groups have been created
this . OnAfterCreatingGroups ( args ) ;
lastGroupingParameters = args . Parameters ;
}
private GroupingParameters lastGroupingParameters ;
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> ռ <EFBFBD> <D5BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӱ<EFBFBD> <D3B0> <EFBFBD> 鴴<EFBFBD> <E9B4B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <returns></returns>
protected virtual GroupingParameters CollectGroupingParameters ( OLVColumn groupByColumn , SortOrder groupByOrder ,
OLVColumn sortByColumn , SortOrder sortByOrder , OLVColumn secondaryColumn , SortOrder secondaryOrder ) {
// If the user tries to group by a non-groupable column, keep the current group by
// settings, but use the non-groupable column for sorting
if ( ! groupByColumn . Groupable & & lastGroupingParameters ! = null ) {
sortByColumn = groupByColumn ;
sortByOrder = groupByOrder ;
groupByColumn = lastGroupingParameters . GroupByColumn ;
groupByOrder = lastGroupingParameters . GroupByOrder ;
}
string titleFormat = this . ShowItemCountOnGroups ? groupByColumn . GroupWithItemCountFormatOrDefault : null ;
string titleSingularFormat = this . ShowItemCountOnGroups ? groupByColumn . GroupWithItemCountSingularFormatOrDefault : null ;
GroupingParameters parms = new GroupingParameters ( this , groupByColumn , groupByOrder ,
sortByColumn , sortByOrder , secondaryColumn , secondaryOrder ,
titleFormat , titleSingularFormat , this . SortGroupItemsByPrimaryColumn ) ;
return parms ;
}
/// <summary>
/// Make a list of groups that should be shown according to the given parameters
/// </summary>
/// <param name="parms"></param>
/// <returns>The list of groups to be created</returns>
/// <remarks>This should not change the state of the control. It is possible that the
/// groups created will not be used. They may simply be discarded.</remarks>
protected virtual IList < OLVGroup > MakeGroups ( GroupingParameters parms ) {
// There is a lot of overlap between this method and FastListGroupingStrategy.MakeGroups()
// Any changes made here may need to be reflected there
// Separate the list view items into groups, using the group key as the descrimanent
NullableDictionary < object , List < OLVListItem > > map = new NullableDictionary < object , List < OLVListItem > > ( ) ;
foreach ( OLVListItem olvi in parms . ListView . Items ) {
object key = parms . GroupByColumn . GetGroupKey ( olvi . RowObject ) ;
if ( ! map . ContainsKey ( key ) )
map [ key ] = new List < OLVListItem > ( ) ;
map [ key ] . Add ( olvi ) ;
}
// Sort the items within each group (unless specifically turned off)
OLVColumn sortColumn = parms . SortItemsByPrimaryColumn ? parms . ListView . GetColumn ( 0 ) : parms . PrimarySort ;
if ( sortColumn ! = null & & parms . PrimarySortOrder ! = SortOrder . None ) {
IComparer < OLVListItem > itemSorter = parms . ItemComparer ? ?
new ColumnComparer ( sortColumn , parms . PrimarySortOrder , parms . SecondarySort , parms . SecondarySortOrder ) ;
foreach ( object key in map . Keys ) {
map [ key ] . Sort ( itemSorter ) ;
}
}
// Make a list of the required groups
List < OLVGroup > groups = new List < OLVGroup > ( ) ;
foreach ( object key in map . Keys ) {
string title = parms . GroupByColumn . ConvertGroupKeyToTitle ( key ) ;
if ( ! String . IsNullOrEmpty ( parms . TitleFormat ) ) {
int count = map [ key ] . Count ;
string format = ( count = = 1 ? parms . TitleSingularFormat : parms . TitleFormat ) ;
try {
title = String . Format ( format , title , count ) ;
} catch ( FormatException ) {
title = "Invalid group format: " + format ;
}
}
OLVGroup lvg = new OLVGroup ( title ) ;
lvg . Collapsible = this . HasCollapsibleGroups ;
lvg . Key = key ;
lvg . SortValue = key as IComparable ;
lvg . Items = map [ key ] ;
if ( parms . GroupByColumn . GroupFormatter ! = null )
parms . GroupByColumn . GroupFormatter ( lvg , parms ) ;
groups . Add ( lvg ) ;
}
// Sort the groups
if ( parms . GroupByOrder ! = SortOrder . None )
groups . Sort ( parms . GroupComparer ? ? new OLVGroupComparer ( parms . GroupByOrder ) ) ;
return groups ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> /<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <EFBFBD> <EEA3AC> <EFBFBD> <EFBFBD> <EFBFBD> ܶ<EFBFBD> <DCB6> ر<EFBFBD> <D8B1> <EFBFBD> ״̬
2021-01-12 08:32:13 +00:00
/// </summary>
public virtual void BuildList ( ) {
if ( this . InvokeRequired )
this . Invoke ( new MethodInvoker ( this . BuildList ) ) ;
else
this . BuildList ( true ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> /<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="shouldPreserveState">If this is true, the control will try to preserve the selection,
/// focused item, and the scroll position (see Remarks)
/// </param>
/// <remarks>
/// <para>
/// Use this method in situations were the contents of the list is basically the same
/// as previously.
/// </para>
/// </remarks>
public virtual void BuildList ( bool shouldPreserveState ) {
if ( this . Frozen )
return ;
Stopwatch sw = Stopwatch . StartNew ( ) ;
this . ApplyExtendedStyles ( ) ;
this . ClearHotItem ( ) ;
int previousTopIndex = this . TopItemIndex ;
Point currentScrollPosition = this . LowLevelScrollPosition ;
IList previousSelection = new ArrayList ( ) ;
Object previousFocus = null ;
if ( shouldPreserveState & & this . objects ! = null ) {
previousSelection = this . SelectedObjects ;
OLVListItem focusedItem = this . FocusedItem as OLVListItem ;
if ( focusedItem ! = null )
previousFocus = focusedItem . RowObject ;
}
IEnumerable objectsToDisplay = this . FilteredObjects ;
this . BeginUpdate ( ) ;
try {
this . Items . Clear ( ) ;
this . ListViewItemSorter = null ;
if ( objectsToDisplay ! = null ) {
// Build a list of all our items and then display them. (Building
// a list and then doing one AddRange is about 10-15% faster than individual adds)
List < ListViewItem > itemList = new List < ListViewItem > ( ) ; // use ListViewItem to avoid co-variant conversion
foreach ( object rowObject in objectsToDisplay ) {
OLVListItem lvi = new OLVListItem ( rowObject ) ;
this . FillInValues ( lvi , rowObject ) ;
itemList . Add ( lvi ) ;
}
this . Items . AddRange ( itemList . ToArray ( ) ) ;
this . Sort ( ) ;
if ( shouldPreserveState ) {
this . SelectedObjects = previousSelection ;
this . FocusedItem = this . ModelToItem ( previousFocus ) ;
}
}
} finally {
this . EndUpdate ( ) ;
}
this . RefreshHotItem ( ) ;
// We can only restore the scroll position after the EndUpdate() because
// of caching that the ListView does internally during a BeginUpdate/EndUpdate pair.
if ( shouldPreserveState ) {
// Restore the scroll position. TopItemIndex is best, but doesn't work
// when the control is grouped.
if ( this . ShowGroups )
this . LowLevelScroll ( currentScrollPosition . X , currentScrollPosition . Y ) ;
else
this . TopItemIndex = previousTopIndex ;
}
// System.Diagnostics.Debug.WriteLine(String.Format("PERF - Building list for {2} objects took {0}ms / {1} ticks", sw.ElapsedMilliseconds, sw.ElapsedTicks, this.GetItemCount()));
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> һ ֱ<D2BB> <D6B1> ʹ <EFBFBD> õ<EFBFBD> <C3B5> <EFBFBD> <EFBFBD> л<EFBFBD> <D0BB> <EFBFBD> <EFBFBD> <EFBFBD> Ϣ
2021-01-12 08:32:13 +00:00
/// </summary>
public virtual void ClearCachedInfo ( )
{
2021-09-12 06:54:13 +00:00
// ObjectListView<65> <77> ǰ<EFBFBD> <C7B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϣ<EFBFBD> <CFA2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <E0BBBA> (<28> <> <EFBFBD> <EFBFBD> <EFBFBD> ܻ<EFBFBD> <DCBB> <EFBFBD> )
2021-01-12 08:32:13 +00:00
}
/// <summary>
/// Apply all required extended styles to our control.
/// </summary>
/// <remarks>
/// <para>
/// Whenever .NET code sets an extended style, it erases all other extended styles
/// that it doesn't use. So, we have to explicit reapply the styles that we have
/// added.
/// </para>
/// <para>
/// Normally, we would override CreateParms property and update
/// the ExStyle member, but ListView seems to ignore all ExStyles that
/// it doesn't already know about. Worse, when we set the LVS_EX_HEADERINALLVIEWS
/// value, bad things happen (the control crashes!).
/// </para>
/// </remarks>
protected virtual void ApplyExtendedStyles ( ) {
const int LVS_EX_SUBITEMIMAGES = 0x00000002 ;
//const int LVS_EX_TRANSPARENTBKGND = 0x00400000;
const int LVS_EX_HEADERINALLVIEWS = 0x02000000 ;
const int STYLE_MASK = LVS_EX_SUBITEMIMAGES | LVS_EX_HEADERINALLVIEWS ;
int style = 0 ;
if ( this . ShowImagesOnSubItems & & ! this . VirtualMode )
style ^ = LVS_EX_SUBITEMIMAGES ;
if ( this . ShowHeaderInAllViews )
style ^ = LVS_EX_HEADERINALLVIEWS ;
NativeMethods . SetExtendedStyle ( this , style , STYLE_MASK ) ;
}
/// <summary>
/// Give the listview a reasonable size of its tiles, based on the number of lines of
/// information that each tile is going to display.
/// </summary>
public virtual void CalculateReasonableTileSize ( ) {
if ( this . Columns . Count < = 0 )
return ;
List < OLVColumn > columns = this . AllColumns . FindAll ( delegate ( OLVColumn x ) {
return ( x . Index = = 0 ) | | x . IsTileViewColumn ;
} ) ;
int imageHeight = ( this . LargeImageList = = null ? 16 : this . LargeImageList . ImageSize . Height ) ;
int dataHeight = ( this . Font . Height + 1 ) * columns . Count ;
int tileWidth = ( this . TileSize . Width = = 0 ? 200 : this . TileSize . Width ) ;
int tileHeight = Math . Max ( this . TileSize . Height , Math . Max ( imageHeight , dataHeight ) ) ;
this . TileSize = new Size ( tileWidth , tileHeight ) ;
}
/// <summary>
/// Rebuild this list for the given view
/// </summary>
/// <param name="view"></param>
public virtual void ChangeToFilteredColumns ( View view ) {
// Store the state
this . SuspendSelectionEvents ( ) ;
IList previousSelection = this . SelectedObjects ;
int previousTopIndex = this . TopItemIndex ;
this . Freeze ( ) ;
this . Clear ( ) ;
List < OLVColumn > columns = this . GetFilteredColumns ( view ) ;
if ( view = = View . Details | | this . ShowHeaderInAllViews ) {
// Make sure all columns have a reasonable LastDisplayIndex
for ( int index = 0 ; index < columns . Count ; index + + )
{
if ( columns [ index ] . LastDisplayIndex = = - 1 )
columns [ index ] . LastDisplayIndex = index ;
}
// ListView will ignore DisplayIndex FOR ALL COLUMNS if there are any errors,
// e.g. duplicates (two columns with the same DisplayIndex) or gaps.
// LastDisplayIndex isn't guaranteed to be unique, so we just sort the columns by
// the last position they were displayed and use that to generate a sequence
// we can use for the DisplayIndex values.
List < OLVColumn > columnsInDisplayOrder = new List < OLVColumn > ( columns ) ;
columnsInDisplayOrder . Sort ( delegate ( OLVColumn x , OLVColumn y ) { return ( x . LastDisplayIndex - y . LastDisplayIndex ) ; } ) ;
int i = 0 ;
foreach ( OLVColumn col in columnsInDisplayOrder )
col . DisplayIndex = i + + ;
}
// ReSharper disable once CoVariantArrayConversion
this . Columns . AddRange ( columns . ToArray ( ) ) ;
if ( view = = View . Details | | this . ShowHeaderInAllViews )
this . ShowSortIndicator ( ) ;
this . UpdateFiltering ( ) ;
this . Unfreeze ( ) ;
// Restore the state
this . SelectedObjects = previousSelection ;
this . TopItemIndex = previousTopIndex ;
this . ResumeSelectionEvents ( ) ;
}
/// <summary>
/// Remove all items from this list
/// </summary>
/// <remark>This method can safely be called from background threads.</remark>
public virtual void ClearObjects ( ) {
if ( this . InvokeRequired )
this . Invoke ( new MethodInvoker ( this . ClearObjects ) ) ;
else
this . SetObjects ( null ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ѷ<EFBFBD> <D1B7> <EFBFBD> <EFBFBD> <EFBFBD> URL<52> <4C> <EFBFBD> ڴ<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
public virtual void ClearUrlVisited ( ) {
this . visitedUrlMap = new Dictionary < string , bool > ( ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
///<2F> <> ѡ <EFBFBD> <D1A1> <EFBFBD> е <EFBFBD> <D0B5> ı <EFBFBD> <C4B1> <EFBFBD> HTML<4D> <4C> ʾ <EFBFBD> <CABE> <EFBFBD> Ƶ<EFBFBD> <C6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϡ<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>Be careful when using this with virtual lists. If the user has selected
/// 10,000,000 rows, this method will faithfully try to copy all of them to the clipboard.
/// From the user's point of view, your program will appear to have hung.</remarks>
public virtual void CopySelectionToClipboard ( ) {
IList selection = this . SelectedObjects ;
if ( selection . Count = = 0 )
return ;
// Use the DragSource object to create the data object, if so configured.
// This relies on the assumption that DragSource will handle the selected objects only.
// It is legal for StartDrag to return null.
object data = null ;
if ( this . CopySelectionOnControlCUsesDragSource & & this . DragSource ! = null )
data = this . DragSource . StartDrag ( this , MouseButtons . Left , this . ModelToItem ( selection [ 0 ] ) ) ;
Clipboard . SetDataObject ( data ? ? new OLVDataObject ( this , selection ) ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> <C4B1> <EFBFBD> HTML<4D> <4C> ʾ <EFBFBD> <CABE> <EFBFBD> Ƶ<EFBFBD> <C6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϡ<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
public virtual void CopyObjectsToClipboard ( IList objectsToCopy ) {
if ( objectsToCopy . Count = = 0 )
return ;
// We don't know where these objects came from, so we can't use the DragSource to create
// the data object, like we do with CopySelectionToClipboard() above.
OLVDataObject dataObject = new OLVDataObject ( this , objectsToCopy ) ;
dataObject . CreateTextFormats ( ) ;
Clipboard . SetDataObject ( dataObject ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> ظ<EFBFBD> <D8B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> html<6D> <6C> ʾ <EFBFBD> <CABE> ʽ
2021-01-12 08:32:13 +00:00
/// </summary>
public virtual string ObjectsToHtml ( IList objectsToConvert ) {
if ( objectsToConvert . Count = = 0 )
return String . Empty ;
OLVExporter exporter = new OLVExporter ( this , objectsToConvert ) ;
return exporter . ExportTo ( OLVExporter . ExportFormat . HTML ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// ȡ<> <C8A1> ѡ <EFBFBD> <D1A1> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
public virtual void DeselectAll ( ) {
NativeMethods . DeselectAllItems ( this ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> ؽ<EFBFBD> <D8BD> <EFBFBD> <EFBFBD> ڸ<EFBFBD> <DAB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ListViewItem<65> <6D>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> գ <EFBFBD> <D5A3> <EFBFBD> <F2B7B5BB> б <EFBFBD> <D0B1> е ĵ<D0B5> һ <EFBFBD> <D2BB> <EFBFBD>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> NULL<4C> <4C>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="itemToFind">The item that is before the item that is returned, or null</param>
/// <returns>A ListViewItem</returns>
public virtual OLVListItem GetNextItem ( OLVListItem itemToFind ) {
if ( this . ShowGroups ) {
bool isFound = ( itemToFind = = null ) ;
foreach ( ListViewGroup group in this . Groups ) {
foreach ( OLVListItem olvi in group . Items ) {
if ( isFound )
return olvi ;
isFound = ( itemToFind = = olvi ) ;
}
}
return null ;
}
if ( this . GetItemCount ( ) = = 0 )
return null ;
if ( itemToFind = = null )
return this . GetItem ( 0 ) ;
if ( itemToFind . Index = = this . GetItemCount ( ) - 1 )
return null ;
return this . GetItem ( itemToFind . Index + 1 ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> ʾ <EFBFBD> <CABE> ˳<EFBFBD> <EFBFBD> <F2B7B5BB> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ؼ<EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD> 飬<EFBFBD> <E9A3AC> <EFBFBD> <EFBFBD> ʾ ˳<CABE> <CBB3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> ˳<EFBFBD> <CBB3> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> ģ<EFBFBD> <C4A3> <EFBFBD> <EFBFBD> <EFBFBD> ʾ ˳<CABE> <CBB3> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <returns></returns>
public virtual OLVListItem GetLastItemInDisplayOrder ( ) {
if ( ! this . ShowGroups )
return this . GetItem ( this . GetItemCount ( ) - 1 ) ;
if ( this . Groups . Count > 0 ) {
ListViewGroup lastGroup = this . Groups [ this . Groups . Count - 1 ] ;
if ( lastGroup . Items . Count > 0 )
return ( OLVListItem ) lastGroup . Items [ lastGroup . Items . Count - 1 ] ;
}
return null ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> ʾ <EFBFBD> <CABE> ˳<EFBFBD> ص<F2B7B5BB> n<EFBFBD> <6E> (<28> <> 0<EFBFBD> <30> ʼ )<29> <>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ؼ<EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD> 飬<EFBFBD> <E9A3AC> <EFBFBD> <EFBFBD> ʾ ˳<CABE> <CBB3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> ˳<EFBFBD> <CBB3> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> ģ<EFBFBD> <C4A3> <EFBFBD> <EFBFBD> <EFBFBD> ʾ ˳<CABE> <CBB3> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public virtual OLVListItem GetNthItemInDisplayOrder ( int n ) {
if ( ! this . ShowGroups | | this . Groups . Count = = 0 )
return this . GetItem ( n ) ;
foreach ( ListViewGroup group in this . Groups ) {
if ( n < group . Items . Count )
return ( OLVListItem ) group . Items [ n ] ;
n - = group . Items . Count ;
}
return null ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
///<2F> <> <EFBFBD> ظ<EFBFBD> <D8B8> <EFBFBD> listviewitem<65> <6D> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ؼ<EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD> 飬<EFBFBD> <E9A3AC> <EFBFBD> <EFBFBD> ʾ ˳<CABE> <CBB3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> ˳<EFBFBD> <CBB3> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> ģ<EFBFBD> <C4A3> <EFBFBD> <EFBFBD> <EFBFBD> ʾ ˳<CABE> <CBB3> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="itemIndex"></param>
/// <returns></returns>
public virtual int GetDisplayOrderOfItemIndex ( int itemIndex ) {
if ( ! this . ShowGroups | | this . Groups . Count = = 0 )
return itemIndex ;
// TODO: This could be optimized
int i = 0 ;
foreach ( ListViewGroup lvg in this . Groups ) {
foreach ( ListViewItem lvi in lvg . Items ) {
if ( lvi . Index = = itemIndex )
return i ;
i + + ;
}
}
return - 1 ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> ؽ<EFBFBD> <D8BD> <EFBFBD> <EFBFBD> ڸ<EFBFBD> <DAB8> <EFBFBD> <EFBFBD> <EFBFBD> ֮ǰ<D6AE> <C7B0> <EFBFBD> ֵ<EFBFBD> ListViewItem<65> <6D>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> գ <EFBFBD> <D5A3> <EFBFBD> <F2B7B5BB> б <EFBFBD> <D0B1> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǵ<EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> NULL<4C> <4C>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="itemToFind">The item that is before the item that is returned</param>
/// <returns>A ListViewItem</returns>
public virtual OLVListItem GetPreviousItem ( OLVListItem itemToFind ) {
if ( this . ShowGroups ) {
OLVListItem previousItem = null ;
foreach ( ListViewGroup group in this . Groups ) {
foreach ( OLVListItem lvi in group . Items ) {
if ( lvi = = itemToFind )
return previousItem ;
previousItem = lvi ;
}
}
return itemToFind = = null ? previousItem : null ;
}
if ( this . GetItemCount ( ) = = 0 )
return null ;
if ( itemToFind = = null )
return this . GetItem ( this . GetItemCount ( ) - 1 ) ;
if ( itemToFind . Index = = 0 )
return null ;
return this . GetItem ( itemToFind . Index - 1 ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> ڸ<EFBFBD> <DAB8> <EFBFBD> λ<EFBFBD> <CEBB> ֮ǰ<D6AE> <C7B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ķ<EFBFBD> <C4B6> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="index">Where to insert the objects</param>
/// <param name="modelObjects">The objects to be inserted</param>
/// <remarks>
/// <para>
/// This operation only makes sense of non-sorted, non-grouped
/// lists, since any subsequent sort/group operation will rearrange
/// the list.
/// </para>
/// <para>This method only works on ObjectListViews and FastObjectListViews.</para>
///</remarks>
public virtual void InsertObjects ( int index , ICollection modelObjects ) {
if ( this . InvokeRequired ) {
this . Invoke ( ( MethodInvoker ) delegate ( ) {
this . InsertObjects ( index , modelObjects ) ;
} ) ;
return ;
}
if ( modelObjects = = null )
return ;
this . BeginUpdate ( ) ;
try {
// Give the world a chance to cancel or change the added objects
ItemsAddingEventArgs args = new ItemsAddingEventArgs ( modelObjects ) ;
this . OnItemsAdding ( args ) ;
if ( args . Canceled )
return ;
modelObjects = args . ObjectsToAdd ;
this . TakeOwnershipOfObjects ( ) ;
ArrayList ourObjects = ObjectListView . EnumerableToArray ( this . Objects , false ) ;
// If we are filtering the list, there is no way to efficiently
// insert the objects, so just put them into our collection and rebuild.
if ( this . IsFiltering ) {
index = Math . Max ( 0 , Math . Min ( index , ourObjects . Count ) ) ;
ourObjects . InsertRange ( index , modelObjects ) ;
this . BuildList ( true ) ;
} else {
this . ListViewItemSorter = null ;
index = Math . Max ( 0 , Math . Min ( index , this . GetItemCount ( ) ) ) ;
int i = index ;
foreach ( object modelObject in modelObjects ) {
if ( modelObject ! = null ) {
ourObjects . Insert ( i , modelObject ) ;
OLVListItem lvi = new OLVListItem ( modelObject ) ;
this . FillInValues ( lvi , modelObject ) ;
this . Items . Insert ( i , lvi ) ;
i + + ;
}
}
for ( i = index ; i < this . GetItemCount ( ) ; i + + ) {
OLVListItem lvi = this . GetItem ( i ) ;
this . SetSubItemImages ( lvi . Index , lvi ) ;
}
this . PostProcessRows ( ) ;
}
// Tell the world that the list has changed
this . SubscribeNotifications ( modelObjects ) ;
this . OnItemsChanged ( new ItemsChangedEventArgs ( ) ) ;
} finally {
this . EndUpdate ( ) ;
}
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> ˱<EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> ģ<EFBFBD> ͵<EFBFBD> <CDB5> У <EFBFBD> <D0A3> <EFBFBD> TRUE
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="model">The model object to look for</param>
/// <returns>Is the row selected</returns>
public bool IsSelected ( object model ) {
OLVListItem item = this . ModelToItem ( model ) ;
return item ! = null & & item . Selected ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> URL<52> Ƿ<EFBFBD> <C7B7> ѱ<EFBFBD> <D1B1> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="url">The string to be consider</param>
/// <returns>Has it been visited</returns>
public virtual bool IsUrlVisited ( string url ) {
return this . visitedUrlMap . ContainsKey ( url ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ListView<65> <77>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="dx">Horizontal delta</param>
/// <param name="dy">Vertical delta</param>
public void LowLevelScroll ( int dx , int dy ) {
NativeMethods . Scroll ( this , dx , dy ) ;
}
/// <summary>
/// Return a point that represents the current horizontal and vertical scroll positions
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public Point LowLevelScrollPosition
{
get {
return new Point ( NativeMethods . GetScrollPosition ( this , true ) , NativeMethods . GetScrollPosition ( this , false ) ) ;
}
}
/// <summary>
2021-09-12 06:54:13 +00:00
///<2F> <> ס <EFBFBD> <D7A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> URL<52> ѱ<EFBFBD> <D1B1> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="url">The url to be remembered</param>
/// <remarks>This does not cause the control be redrawn</remarks>
public virtual void MarkUrlVisited ( string url ) {
this . visitedUrlMap [ url ] = true ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ķ<EFBFBD> <C4B6> <EFBFBD> <F3BCAFBA> ƶ<EFBFBD> <C6B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-09-12 06:54:13 +00:00
/// <remarks><3E> ˲<EFBFBD> <CBB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ObjectListViews<77> <73> <EFBFBD> <EFBFBD> <EFBFBD> 塣</remarks>
2021-01-12 08:32:13 +00:00
/// <param name="index"></param>
/// <param name="modelObjects"></param>
public virtual void MoveObjects ( int index , ICollection modelObjects ) {
// We are going to remove all the given objects from our list
// and then insert them at the given location
this . TakeOwnershipOfObjects ( ) ;
ArrayList ourObjects = ObjectListView . EnumerableToArray ( this . Objects , false ) ;
List < int > indicesToRemove = new List < int > ( ) ;
foreach ( object modelObject in modelObjects ) {
if ( modelObject ! = null ) {
int i = this . IndexOf ( modelObject ) ;
if ( i > = 0 ) {
indicesToRemove . Add ( i ) ;
ourObjects . Remove ( modelObject ) ;
if ( i < = index )
index - - ;
}
}
}
// Remove the objects in reverse order so earlier
// deletes don't change the index of later ones
indicesToRemove . Sort ( ) ;
indicesToRemove . Reverse ( ) ;
try {
this . BeginUpdate ( ) ;
foreach ( int i in indicesToRemove ) {
this . Items . RemoveAt ( i ) ;
}
this . InsertObjects ( index , modelObjects ) ;
} finally {
this . EndUpdate ( ) ;
}
}
/// <summary>
2021-09-12 06:54:13 +00:00
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ڸ<EFBFBD> <DAB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> µ<EFBFBD> <C2B5> <EFBFBD> Ŀ<EFBFBD> <C4BF> ʲô<CAB2> <C3B4>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
new public ListViewHitTestInfo HitTest ( int x , int y ) {
// Everything costs something. Playing with the layout of the header can cause problems
// with the hit testing. If the header shrinks, the underlying control can throw a tantrum.
try {
return base . HitTest ( x , y ) ;
} catch ( ArgumentOutOfRangeException ) {
return new ListViewHitTestInfo ( null , null , ListViewHitTestLocations . None ) ;
}
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// ʹ <> <CAB9> Windows<77> ؼ<EFBFBD> <D8BC> <EFBFBD> SUBITEMHITTEST<53> <54> Ϣִ<CFA2> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ԡ<EFBFBD>
/// <20> <> <EFBFBD> ṩ<EFBFBD> ˱<EFBFBD> ListView.HitTest()<29> <> <EFBFBD> ṩ<EFBFBD> <E1B9A9> <EFBFBD> й<EFBFBD> <D0B9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϣ<EFBFBD> <CFA2>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
protected OlvListViewHitTestInfo LowLevelHitTest ( int x , int y ) {
// If it's not even in the control, don't bother with anything else
if ( ! this . ClientRectangle . Contains ( x , y ) )
return new OlvListViewHitTestInfo ( null , null , 0 , null , 0 ) ;
// Is the point over the header?
OlvListViewHitTestInfo . HeaderHitTestInfo headerHitTestInfo = this . HeaderControl . HitTest ( x , y ) ;
if ( headerHitTestInfo ! = null )
return new OlvListViewHitTestInfo ( this , headerHitTestInfo . ColumnIndex , headerHitTestInfo . IsOverCheckBox , headerHitTestInfo . OverDividerIndex ) ;
// Call the native hit test method, which is a little confusing.
NativeMethods . LVHITTESTINFO lParam = new NativeMethods . LVHITTESTINFO ( ) ;
lParam . pt_x = x ;
lParam . pt_y = y ;
int index = NativeMethods . HitTest ( this , ref lParam ) ;
// Setup the various values we need to make our hit test structure
bool isGroupHit = ( lParam . flags & ( int ) HitTestLocationEx . LVHT_EX_GROUP ) ! = 0 ;
OLVListItem hitItem = isGroupHit | | index = = - 1 ? null : this . GetItem ( index ) ;
OLVListSubItem subItem = ( this . View = = View . Details & & hitItem ! = null ) ? hitItem . GetSubItem ( lParam . iSubItem ) : null ;
// Figure out which group is involved in the hit test. This is a little complicated:
// If the list is virtual:
// - the returned value is list view item index
// - iGroup is the *index* of the hit group.
// If the list is not virtual:
// - iGroup is always -1.
// - if the point is over a group, the returned value is the *id* of the hit group.
// - if the point is not over a group, the returned value is list view item index.
OLVGroup group = null ;
if ( this . ShowGroups & & this . OLVGroups ! = null ) {
if ( this . VirtualMode ) {
group = lParam . iGroup > = 0 & & lParam . iGroup < this . OLVGroups . Count ? this . OLVGroups [ lParam . iGroup ] : null ;
} else {
if ( isGroupHit ) {
foreach ( OLVGroup olvGroup in this . OLVGroups ) {
if ( olvGroup . GroupId = = index ) {
group = olvGroup ;
break ;
}
}
}
}
}
OlvListViewHitTestInfo olvListViewHitTest = new OlvListViewHitTestInfo ( hitItem , subItem , lParam . flags , group , lParam . iSubItem ) ;
// System.Diagnostics.Debug.WriteLine(String.Format("HitTest({0}, {1})=>{2}", x, y, olvListViewHitTest));
return olvListViewHitTest ;
}
/// <summary>
/// What is under the given point? This takes the various parts of a cell into accout, including
/// any custom parts that a custom renderer might use
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns>An information block about what is under the point</returns>
public virtual OlvListViewHitTestInfo OlvHitTest ( int x , int y ) {
OlvListViewHitTestInfo hti = this . LowLevelHitTest ( x , y ) ;
// There is a bug/"feature" of the ListView concerning hit testing.
// If FullRowSelect is false and the point is over cell 0 but not on
// the text or icon, HitTest will not register a hit. We could turn
// FullRowSelect on, do the HitTest, and then turn it off again, but
// toggling FullRowSelect in that way messes up the tooltip in the
// underlying control. So we have to find another way.
//
// It's too hard to try to write the hit test from scratch. Grouping (for
// example) makes it just too complicated. So, we have to use HitTest
// but try to get around its limits.
//
// First step is to determine if the point was within column 0.
// If it was, then we only have to determine if there is an actual row
// under the point. If there is, then we know that the point is over cell 0.
// So we try a Battleship-style approach: is there a subcell to the right
// of cell 0? This will return a false negative if column 0 is the rightmost column,
// so we also check for a subcell to the left. But if only column 0 is visible,
// then that will fail too, so we check for something at the very left of the
// control.
//
// This will still fail under pathological conditions. If column 0 fills
// the whole listview and no part of the text column 0 is visible
// (because it is horizontally scrolled offscreen), then the hit test will fail.
// Are we in the buggy context? Details view, not full row select, and
// failing to find anything
if ( hti . Item = = null & & ! this . FullRowSelect & & this . View = = View . Details ) {
// Is the point within the column 0? If it is, maybe it should have been a hit.
// Let's test slightly to the right and then to left of column 0. Hopefully one
// of those will hit a subitem
Point sides = NativeMethods . GetScrolledColumnSides ( this , 0 ) ;
if ( x > = sides . X & & x < = sides . Y ) {
// We look for:
// - any subitem to the right of cell 0?
// - any subitem to the left of cell 0?
// - cell 0 at the left edge of the screen
hti = this . LowLevelHitTest ( sides . Y + 4 , y ) ;
if ( hti . Item = = null )
hti = this . LowLevelHitTest ( sides . X - 4 , y ) ;
if ( hti . Item = = null )
hti = this . LowLevelHitTest ( 4 , y ) ;
if ( hti . Item ! = null ) {
// We hit something! So, the original point must have been in cell 0
hti . ColumnIndex = 0 ;
hti . SubItem = hti . Item . GetSubItem ( 0 ) ;
hti . Location = ListViewHitTestLocations . None ;
hti . HitTestLocation = HitTestLocation . InCell ;
}
}
}
if ( this . OwnerDraw )
this . CalculateOwnerDrawnHitTest ( hti , x , y ) ;
else
this . CalculateStandardHitTest ( hti , x , y ) ;
return hti ;
}
/// <summary>
/// Perform a hit test when the control is not owner drawn
/// </summary>
/// <param name="hti"></param>
/// <param name="x"></param>
/// <param name="y"></param>
protected virtual void CalculateStandardHitTest ( OlvListViewHitTestInfo hti , int x , int y ) {
// Standard hit test works fine for the primary column
if ( this . View ! = View . Details | | hti . ColumnIndex = = 0 | |
hti . SubItem = = null | | hti . Column = = null )
return ;
Rectangle cellBounds = hti . SubItem . Bounds ;
bool hasImage = ( this . GetActualImageIndex ( hti . SubItem . ImageSelector ) ! = - 1 ) ;
// Unless we say otherwise, it was an general incell hit
hti . HitTestLocation = HitTestLocation . InCell ;
// Check if the point is over where an image should be.
// If there is a checkbox or image there, tag it and exit.
Rectangle r = cellBounds ;
r . Width = this . SmallImageSize . Width ;
if ( r . Contains ( x , y ) ) {
if ( hti . Column . CheckBoxes ) {
hti . HitTestLocation = HitTestLocation . CheckBox ;
return ;
}
if ( hasImage ) {
hti . HitTestLocation = HitTestLocation . Image ;
return ;
}
}
// Figure out where the text actually is and if the point is in it
// The standard HitTest assumes that any point inside a subitem is
// a hit on Text -- which is clearly not true.
Rectangle textBounds = cellBounds ;
textBounds . X + = 4 ;
if ( hasImage )
textBounds . X + = this . SmallImageSize . Width ;
Size proposedSize = new Size ( textBounds . Width , textBounds . Height ) ;
Size textSize = TextRenderer . MeasureText ( hti . SubItem . Text , this . Font , proposedSize , TextFormatFlags . EndEllipsis | TextFormatFlags . SingleLine | TextFormatFlags . NoPrefix ) ;
textBounds . Width = textSize . Width ;
switch ( hti . Column . TextAlign ) {
case HorizontalAlignment . Center :
textBounds . X + = ( cellBounds . Right - cellBounds . Left - textSize . Width ) / 2 ;
break ;
case HorizontalAlignment . Right :
textBounds . X = cellBounds . Right - textSize . Width ;
break ;
}
if ( textBounds . Contains ( x , y ) ) {
hti . HitTestLocation = HitTestLocation . Text ;
}
}
/// <summary>
/// Perform a hit test when the control is owner drawn. This hands off responsibility
/// to the renderer.
/// </summary>
/// <param name="hti"></param>
/// <param name="x"></param>
/// <param name="y"></param>
protected virtual void CalculateOwnerDrawnHitTest ( OlvListViewHitTestInfo hti , int x , int y ) {
// If the click wasn't on an item, give up
if ( hti . Item = = null )
return ;
// If the list is showing column, but they clicked outside the columns, also give up
if ( this . View = = View . Details & & hti . Column = = null )
return ;
// Which renderer was responsible for drawing that point
IRenderer renderer = this . View = = View . Details
? this . GetCellRenderer ( hti . RowObject , hti . Column )
: this . ItemRenderer ;
// We can't decide who was responsible. Give up
if ( renderer = = null )
return ;
// Ask the responsible renderer what is at that point
renderer . HitTest ( hti , x , y ) ;
}
/// <summary>
/// Pause (or unpause) all animations in the list
/// </summary>
/// <param name="isPause">true to pause, false to unpause</param>
public virtual void PauseAnimations ( bool isPause ) {
for ( int i = 0 ; i < this . Columns . Count ; i + + ) {
OLVColumn col = this . GetColumn ( i ) ;
ImageRenderer renderer = col . Renderer as ImageRenderer ;
if ( renderer ! = null )
renderer . Paused = isPause ;
}
}
/// <summary>
/// Rebuild the columns based upon its current view and column visibility settings
/// </summary>
public virtual void RebuildColumns ( ) {
this . ChangeToFilteredColumns ( this . View ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> ListView<65> <77> ɾ<EFBFBD> <C9BE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="modelObject">The model to be removed</param>
/// <remarks>See RemoveObjects() for more details
/// <para>This method is thread-safe.</para>
/// </remarks>
public virtual void RemoveObject ( object modelObject ) {
if ( this . InvokeRequired )
this . Invoke ( ( MethodInvoker ) delegate ( ) { this . RemoveObject ( modelObject ) ; } ) ;
else
this . RemoveObjects ( new object [ ] { modelObject } ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
///<2F> ӿؼ<D3BF> <D8BC> <EFBFBD> <EFBFBD> Ƴ<EFBFBD> <C6B3> <EFBFBD> <EFBFBD> и<EFBFBD> <D0B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="modelObjects">Collection of objects to be removed</param>
/// <remarks>
/// <para>Nulls and model objects that are not in the ListView are silently ignored.</para>
/// <para>This method is thread-safe.</para>
/// </remarks>
public virtual void RemoveObjects ( ICollection modelObjects ) {
if ( this . InvokeRequired ) {
this . Invoke ( ( MethodInvoker ) delegate ( ) { this . RemoveObjects ( modelObjects ) ; } ) ;
return ;
}
if ( modelObjects = = null )
return ;
this . BeginUpdate ( ) ;
try {
// Give the world a chance to cancel or change the added objects
ItemsRemovingEventArgs args = new ItemsRemovingEventArgs ( modelObjects ) ;
this . OnItemsRemoving ( args ) ;
if ( args . Canceled )
return ;
modelObjects = args . ObjectsToRemove ;
this . TakeOwnershipOfObjects ( ) ;
ArrayList ourObjects = ObjectListView . EnumerableToArray ( this . Objects , false ) ;
foreach ( object modelObject in modelObjects ) {
if ( modelObject ! = null ) {
// ReSharper disable PossibleMultipleEnumeration
int i = ourObjects . IndexOf ( modelObject ) ;
if ( i > = 0 )
ourObjects . RemoveAt ( i ) ;
// ReSharper restore PossibleMultipleEnumeration
i = this . IndexOf ( modelObject ) ;
if ( i > = 0 )
this . Items . RemoveAt ( i ) ;
}
}
this . PostProcessRows ( ) ;
// Tell the world that the list has changed
this . UnsubscribeNotifications ( modelObjects ) ;
this . OnItemsChanged ( new ItemsChangedEventArgs ( ) ) ;
} finally {
this . EndUpdate ( ) ;
}
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// ѡ <> <D1A1> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
public virtual void SelectAll ( ) {
NativeMethods . SelectAllItems ( this ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
///<2F> <> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> ½<EFBFBD> <C2BD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> ̶<EFBFBD> <CCB6> ĸ<EFBFBD> <C4B8> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD>
///<2F> <> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <EFBFBD> <F1B2BBBB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>
/// <para>
2021-09-12 06:54:13 +00:00
/// <20> ˷<EFBFBD> <CBB7> <EFBFBD> ʹ <EFBFBD> <CAB9> ListView<65> <77> ԭ<EFBFBD> <D4AD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD>
/// <20> <> <EFBFBD> м<EFBFBD> <D0BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƣ<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </para>
/// <list type="bullet">
2021-09-12 06:54:13 +00:00
/// <item><description><3E> <> <EFBFBD> <EFBFBD> owner drawnģʽ <C4A3> ²<EFBFBD> <C2B2> ܺܺõع<C3B5> <D8B9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> owner drawn<77> <6E> <EFBFBD> <EFBFBD> ģʽ <C4A3> £<EFBFBD>
/// ÿ<> <C3BF> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <EFBFBD> <F1B6BCBB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> DZ<EFBFBD> <C7B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> ı <EFBFBD> <C4B1> <EFBFBD> <EFBFBD> <EFBFBD> </description></item>
/// <item><description><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ǻܺã<DCBA> <C3A3> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> ϻ<EFBFBD> <CFBB> Ƶġ<C6B5> </description></item>
/// <item><description><3E> <> <EFBFBD> <EFBFBD> XP<58> <50> <EFBFBD> <EFBFBD> ȫ<EFBFBD> <C8AB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> á<EFBFBD> </description></item>
/// <item><description><3E> <> Ȼ<EFBFBD> <C8BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ý<EFBFBD> <C3BD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ɫʱ<C9AB> <CAB1> Ч<EFBFBD> <D0A7> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> </description></item>
2021-01-12 08:32:13 +00:00
/// </list>
/// <para>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Щ<EFBFBD> <D0A9> <EFBFBD> ƣ<EFBFBD> ԭ<EFBFBD> <D4AD> ˮӡ<CBAE> <D3A1> <EFBFBD> ൱<EFBFBD> <E0B5B1> <EFBFBD> <EFBFBD> <EFBFBD> ˡ<EFBFBD>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʵ<EFBFBD> ı <EFBFBD> <C4B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> OverlayImageʹ <65> õİ<C3B5> <EFBFBD> <CDB8> <EFBFBD> <EFBFBD> <EFBFBD> ǡ<EFBFBD>
///<2F> 븲<EFBFBD> <EBB8B2> <EFBFBD> <EFBFBD> <EFBFBD> ȣ <EFBFBD> <C8A3> <EFBFBD> <EFBFBD> <EFBFBD> Ҳ<EFBFBD> <D2B2> <EFBFBD> <EFBFBD> <EFBFBD> Ե<EFBFBD> <D4B5> <EFBFBD> <EFBFBD> ƣ<EFBFBD> <C6A3> <EFBFBD> Ϊ<EFBFBD> <CEAA> ʹ <EFBFBD> <CAB9> MDIӦ<49> ó<EFBFBD> <C3B3> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> <EFBFBD> Ҳ<EFBFBD> <D2B2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </para>
2021-09-12 06:54:13 +00:00
/// <para><3E> <> <EFBFBD> ô<EFBFBD> ѡ <EFBFBD> <EFBFBD> <EEBDAB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> </para>
2021-01-12 08:32:13 +00:00
/// </remarks>
/// <param name="image">The image to be drawn. If null, any existing image will be removed.</param>
public void SetNativeBackgroundWatermark ( Image image ) {
NativeMethods . SetBackgroundImage ( this , image , true , false , 0 , 0 ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪListView<65> ı <EFBFBD> <C4B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ա<EFBFBD> <D4B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> Ը<EFBFBD> <D4B8> <EFBFBD> <EFBFBD> İٷֱ<D9B7> ƫ<EFBFBD> <C6AB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>
2021-09-12 06:54:13 +00:00
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <see cref="SetNativeBackgroundWatermark"/><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͬ<EFBFBD> <CDAC> <EFBFBD> <EFBFBD> .
/// <20> <> ʹ <EFBFBD> ø÷<C3B8> <C3B7> <EFBFBD> ֮ǰ<D6AE> <C7B0> <EFBFBD> <EFBFBD> ȷ<EFBFBD> <C8B7> <EFBFBD> ˽<EFBFBD> <CBBD> <EFBFBD> Щ<EFBFBD> <D0A9> <EFBFBD> ơ<EFBFBD> </para>
/// <para><3E> <> <EFBFBD> dz<EFBFBD> <C7B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <see cref="System.Windows.Forms.Control.BackgroundImage"/> <20> <> <EFBFBD> ԣ<EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> Backround Image<67> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȷ<EFBFBD> <C8B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <CDB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> --<2D> <> <EFBFBD> <EFBFBD> <EFBFBD> <CDB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> ɫ<EFBFBD> <C9AB> <EFBFBD> <EFBFBD> <EFBFBD> ַ<EFBFBD> <D6B7> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ⡣</para>
/// <para><3E> <> <EFBFBD> ô<EFBFBD> ѡ <EFBFBD> <EFBFBD> <EEBDAB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ˮӡ<CBAE> <D3A1> </para>
2021-01-12 08:32:13 +00:00
/// </remarks>
/// <param name="image">The image to be drawn. If null, any existing image will be removed.</param>
/// <param name="xOffset">The horizontal percentage where the image will be placed. 0 is absolute left, 100 is absolute right.</param>
/// <param name="yOffset">The vertical percentage where the image will be placed.</param>
public void SetNativeBackgroundImage ( Image image , int xOffset , int yOffset ) {
NativeMethods . SetBackgroundImage ( this , image , false , false , xOffset , yOffset ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪListView<65> <77> ƽ <EFBFBD> ̱<EFBFBD> <CCB1> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>
2021-09-12 06:54:13 +00:00
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <see cref="SetNativeBackgroundWatermark"/> <20> <> <see cref="SetNativeBackgroundImage"/> <20> <> ͬ<EFBFBD> <CDAC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> .
/// <20> <> ʹ <EFBFBD> ø÷<C3B8> <C3B7> <EFBFBD> ֮ǰ<D6AE> <C7B0> <EFBFBD> <EFBFBD> ȷ<EFBFBD> <C8B7> <EFBFBD> ˽<EFBFBD> <CBBD> <EFBFBD> Щ<EFBFBD> <D0A9> <EFBFBD> ơ<EFBFBD> </para>
2021-01-12 08:32:13 +00:00
/// </remarks>
2021-09-12 06:54:13 +00:00
/// <param name="image">Ҫ<> <D2AA> <EFBFBD> Ƶ<EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊnull<6C> <6C> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɾ<EFBFBD> <C9BE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> </param>
2021-01-12 08:32:13 +00:00
public void SetNativeBackgroundTiledImage ( Image image ) {
NativeMethods . SetBackgroundImage ( this , image , false , true , 0 , 0 ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> ý<EFBFBD> <C3BD> ڴ<EFBFBD> <DAB4> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʾ <EFBFBD> Ķ<EFBFBD> <C4B6> ϡ<F3BCAFBA>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-09-12 06:54:13 +00:00
/// <remark><3E> <> <EFBFBD> ԴӺ<D4B4> ̨<EFBFBD> ̰߳<DFB3> ȫ<EFBFBD> ص<EFBFBD> <D8B5> ô˷<C3B4> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> </remark>
/// <remarks><3E> <> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> </remarks>
2021-01-12 08:32:13 +00:00
/// <param name="collection">The objects to be displayed</param>
public virtual void SetObjects ( IEnumerable collection ) {
this . SetObjects ( collection , false ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> ý<EFBFBD> <C3BD> ڴ<EFBFBD> <DAB4> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʾ <EFBFBD> Ķ<EFBFBD> <C4B6> ϡ<F3BCAFBA>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-09-12 06:54:13 +00:00
/// <remark><3E> <> <EFBFBD> ԴӺ<D4B4> ̨<EFBFBD> ̰߳<DFB3> ȫ<EFBFBD> ص<EFBFBD> <D8B5> ô˷<C3B4> <CBB7> <EFBFBD> .</remark>
/// <remarks><3E> <> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> </remarks>
2021-01-12 08:32:13 +00:00
/// <param name="collection">The objects to be displayed</param>
2021-09-12 06:54:13 +00:00
/// <param name="preserveState"><3E> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> ܱ<EFBFBD> <DCB1> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ״̬<D7B4> <CCAC> </param>
2021-01-12 08:32:13 +00:00
public virtual void SetObjects ( IEnumerable collection , bool preserveState ) {
if ( this . InvokeRequired ) {
this . Invoke ( ( MethodInvoker ) delegate { this . SetObjects ( collection , preserveState ) ; } ) ;
return ;
}
// Give the world a chance to cancel or change the assigned collection
ItemsChangingEventArgs args = new ItemsChangingEventArgs ( this . objects , collection ) ;
this . OnItemsChanging ( args ) ;
if ( args . Canceled )
return ;
collection = args . NewObjects ;
// If we own the current list and they change to another list, we don't own it anymore
if ( this . isOwnerOfObjects & & ! ReferenceEquals ( this . objects , collection ) )
this . isOwnerOfObjects = false ;
this . objects = collection ;
this . BuildList ( preserveState ) ;
// Tell the world that the list has changed
this . UpdateNotificationSubscriptions ( this . objects ) ;
this . OnItemsChanged ( new ItemsChangedEventArgs ( ) ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> µ<EFBFBD> ListView<65> С <EFBFBD>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> <C4A3> <EFBFBD> в<EFBFBD> <D0B2> <EFBFBD> <EFBFBD> ڣ<EFBFBD> <DAA3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӹ<EFBFBD> ģ<EFBFBD> ͡<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="modelObject">The model to be updated</param>
/// <remarks>
/// <para>
/// See <see cref="RemoveObjects(ICollection)"/> for more details
/// </para>
2021-09-12 06:54:13 +00:00
/// <para><3E> ˷<EFBFBD> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ̰߳<DFB3> ȫ<EFBFBD> ġ<EFBFBD> </para>
/// <para><3E> ˷<EFBFBD> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> </para>
/// <para><3E> ˷<EFBFBD> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ObjectListViews<77> <73> FastObjectListViews<77> <73> </para>
2021-01-12 08:32:13 +00:00
/// </remarks>
public virtual void UpdateObject ( object modelObject ) {
if ( this . InvokeRequired )
this . Invoke ( ( MethodInvoker ) delegate ( ) { this . UpdateObject ( modelObject ) ; } ) ;
else
this . UpdateObjects ( new object [ ] { modelObject } ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȵ<EFBFBD> Ԥ<EFBFBD> ȴ<EFBFBD> <C8B4> ڵ<EFBFBD> ģ<EFBFBD> ͡<EFBFBD>
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ؼ<EFBFBD> <D8BC> в<EFBFBD> <D0B2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> κ<EFBFBD> ģ<EFBFBD> ͣ<EFBFBD> <CDA3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǡ<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="modelObjects">Collection of objects to be updated/added</param>
/// <remarks>
2021-09-12 06:54:13 +00:00
/// <para><3E> ˷<EFBFBD> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> </para>
/// <para>nullֵ<6C> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> <EFBFBD> ԡ<EFBFBD> </para>
/// <para><3E> ˷<EFBFBD> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ̰߳<DFB3> ȫ<EFBFBD> ġ<EFBFBD> </para>
/// <para><3E> ˷<EFBFBD> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ObjectListViews<77> <73> FastObjectListViews<77> <73> </para>
2021-01-12 08:32:13 +00:00
/// </remarks>
public virtual void UpdateObjects ( ICollection modelObjects ) {
if ( this . InvokeRequired ) {
this . Invoke ( ( MethodInvoker ) delegate ( ) { this . UpdateObjects ( modelObjects ) ; } ) ;
return ;
}
if ( modelObjects = = null | | modelObjects . Count = = 0 )
return ;
this . BeginUpdate ( ) ;
try {
this . UnsubscribeNotifications ( modelObjects ) ;
ArrayList objectsToAdd = new ArrayList ( ) ;
this . TakeOwnershipOfObjects ( ) ;
ArrayList ourObjects = ObjectListView . EnumerableToArray ( this . Objects , false ) ;
foreach ( object modelObject in modelObjects ) {
if ( modelObject ! = null ) {
int i = ourObjects . IndexOf ( modelObject ) ;
if ( i < 0 )
objectsToAdd . Add ( modelObject ) ;
else {
ourObjects [ i ] = modelObject ;
OLVListItem olvi = this . ModelToItem ( modelObject ) ;
if ( olvi ! = null ) {
olvi . RowObject = modelObject ;
this . RefreshItem ( olvi ) ;
}
}
}
}
this . PostProcessRows ( ) ;
this . AddObjects ( objectsToAdd ) ;
// Tell the world that the list has changed
this . SubscribeNotifications ( modelObjects ) ;
this . OnItemsChanged ( new ItemsChangedEventArgs ( ) ) ;
}
finally {
this . EndUpdate ( ) ;
}
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> ĵ<EFBFBD> ǰģ<C7B0> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> ϶<EFBFBD> INotifyPropertyChanged<65> ¼<EFBFBD> <C2BC> <EFBFBD> <EFBFBD> κζ<CEBA> <CEB6> ģ<EFBFBD>
/// <20> Ա<EFBFBD> <D4B1> <EFBFBD> <EFBFBD> Dz<EFBFBD> <C7B2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> <C4A3> <EFBFBD> ϵ<EFBFBD> <CFB5> ¼<EFBFBD> <C2BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϵ<EFBFBD> <CFB5> ¼<EFBFBD> <C2BC> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>This does nothing if UseNotifyPropertyChanged is false.</remarks>
/// <param name="collection"></param>
protected virtual void UpdateNotificationSubscriptions ( IEnumerable collection ) {
if ( ! this . UseNotifyPropertyChanged )
return ;
// We could calculate a symmetric difference between the old models and the new models
// except that we don't have the previous models at this point.
this . UnsubscribeNotifications ( null ) ;
this . SubscribeNotifications ( collection ? ? this . Objects ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ObjectListView<65> Ƿ<EFBFBD> Ӧ<EFBFBD> <D3A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> ϵ<EFBFBD> INotifyPropertyChanged<65> ¼<EFBFBD> <C2BC> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>
/// <para>
2021-01-23 15:35:30 +00:00
/// <20> <> Ӧ<EFBFBD> <D3A6> <EFBFBD> ڵ<EFBFBD> <DAB5> <EFBFBD> SetObjects()֮ǰ<D6AE> <C7B0> <EFBFBD> á<EFBFBD> <C3A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪFalse<73> <65> ObjectListView<65> <77> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ǰģ<C7B0> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </para>
2021-01-23 15:35:30 +00:00
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> Ͻ<EFBFBD> <CFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊtrue<75> <65> ObjectListView<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> г <EFBFBD> <D0B3> Զ<EFBFBD> <D4B6> ĸ<EFBFBD> <C4B8> <EFBFBD> ֪ͨ<CDA8> <D6AA> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> 10,000,000<30> <30> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫһ Щʱ<D0A9> 䡣</para>
2021-01-12 08:32:13 +00:00
/// </remarks>
[ Category ( "ObjectListView" ) ,
Description ( "Should ObjectListView listen for property changed events on the model objects?" ) ,
DefaultValue ( false ) ]
public bool UseNotifyPropertyChanged {
get { return this . useNotifyPropertyChanged ; }
set {
if ( this . useNotifyPropertyChanged = = value )
return ;
this . useNotifyPropertyChanged = value ;
if ( value )
this . SubscribeNotifications ( this . Objects ) ;
else
this . UnsubscribeNotifications ( null ) ;
}
}
private bool useNotifyPropertyChanged ;
/// <summary>
/// Subscribe to INotifyPropertyChanges on the given collection of objects.
/// </summary>
/// <param name="models"></param>
protected void SubscribeNotifications ( IEnumerable models ) {
if ( ! this . UseNotifyPropertyChanged | | models = = null )
return ;
foreach ( object x in models ) {
INotifyPropertyChanged notifier = x as INotifyPropertyChanged ;
if ( notifier ! = null & & ! subscribedModels . ContainsKey ( notifier ) ) {
notifier . PropertyChanged + = HandleModelOnPropertyChanged ;
subscribedModels [ notifier ] = notifier ;
}
}
}
/// <summary>
/// Unsubscribe from INotifyPropertyChanges on the given collection of objects.
/// If the given collection is null, unsubscribe from all current subscriptions
/// </summary>
/// <param name="models"></param>
protected void UnsubscribeNotifications ( IEnumerable models ) {
if ( models = = null ) {
foreach ( INotifyPropertyChanged notifier in this . subscribedModels . Keys ) {
notifier . PropertyChanged - = HandleModelOnPropertyChanged ;
}
subscribedModels = new Hashtable ( ) ;
} else {
foreach ( object x in models ) {
INotifyPropertyChanged notifier = x as INotifyPropertyChanged ;
if ( notifier ! = null ) {
notifier . PropertyChanged - = HandleModelOnPropertyChanged ;
subscribedModels . Remove ( notifier ) ;
}
}
}
}
private void HandleModelOnPropertyChanged ( object sender , PropertyChangedEventArgs propertyChangedEventArgs ) {
// System.Diagnostics.Debug.WriteLine(String.Format("PropertyChanged: '{0}' on '{1}", propertyChangedEventArgs.PropertyName, sender));
this . RefreshObject ( sender ) ;
}
private Hashtable subscribedModels = new Hashtable ( ) ;
#endregion
#region Save / Restore State
/// <summary>
/// Return a byte array that represents the current state of the ObjectListView, such
/// that the state can be restored by RestoreState()
/// </summary>
/// <remarks>
/// <para>The state of an ObjectListView includes the attributes that the user can modify:
/// <list type="bullet">
/// <item><description>current view (i.e. Details, Tile, Large Icon...)</description></item>
/// <item><description>sort column and direction</description></item>
/// <item><description>column order</description></item>
/// <item><description>column widths</description></item>
/// <item><description>column visibility</description></item>
/// </list>
/// </para>
/// <para>
/// It does not include selection or the scroll position.
/// </para>
/// </remarks>
/// <returns>A byte array representing the state of the ObjectListView</returns>
public virtual byte [ ] SaveState ( ) {
ObjectListViewState olvState = new ObjectListViewState ( ) ;
olvState . VersionNumber = 1 ;
olvState . NumberOfColumns = this . AllColumns . Count ;
olvState . CurrentView = this . View ;
// If we have a sort column, it is possible that it is not currently being shown, in which
// case, it's Index will be -1. So we calculate its index directly. Technically, the sort
// column does not even have to a member of AllColumns, in which case IndexOf will return -1,
// which is works fine since we have no way of restoring such a column anyway.
if ( this . PrimarySortColumn ! = null )
olvState . SortColumn = this . AllColumns . IndexOf ( this . PrimarySortColumn ) ;
olvState . LastSortOrder = this . PrimarySortOrder ;
olvState . IsShowingGroups = this . ShowGroups ;
if ( this . AllColumns . Count > 0 & & this . AllColumns [ 0 ] . LastDisplayIndex = = - 1 )
this . RememberDisplayIndicies ( ) ;
foreach ( OLVColumn column in this . AllColumns ) {
olvState . ColumnIsVisible . Add ( column . IsVisible ) ;
olvState . ColumnDisplayIndicies . Add ( column . LastDisplayIndex ) ;
olvState . ColumnWidths . Add ( column . Width ) ;
}
// Now that we have stored our state, convert it to a byte array
using ( MemoryStream ms = new MemoryStream ( ) ) {
BinaryFormatter serializer = new BinaryFormatter ( ) ;
serializer . AssemblyFormat = FormatterAssemblyStyle . Simple ;
serializer . Serialize ( ms , olvState ) ;
return ms . ToArray ( ) ;
}
}
/// <summary>
/// Restore the state of the control from the given string, which must have been
/// produced by SaveState()
/// </summary>
/// <param name="state">A byte array returned from SaveState()</param>
/// <returns>Returns true if the state was restored</returns>
public virtual bool RestoreState ( byte [ ] state ) {
using ( MemoryStream ms = new MemoryStream ( state ) ) {
BinaryFormatter deserializer = new BinaryFormatter ( ) ;
ObjectListViewState olvState ;
try {
olvState = deserializer . Deserialize ( ms ) as ObjectListViewState ;
} catch ( System . Runtime . Serialization . SerializationException ) {
return false ;
}
// The number of columns has changed. We have no way to match old
// columns to the new ones, so we just give up.
if ( olvState = = null | | olvState . NumberOfColumns ! = this . AllColumns . Count )
return false ;
if ( olvState . SortColumn = = - 1 ) {
this . PrimarySortColumn = null ;
this . PrimarySortOrder = SortOrder . None ;
} else {
this . PrimarySortColumn = this . AllColumns [ olvState . SortColumn ] ;
this . PrimarySortOrder = olvState . LastSortOrder ;
}
for ( int i = 0 ; i < olvState . NumberOfColumns ; i + + ) {
OLVColumn column = this . AllColumns [ i ] ;
column . Width = ( int ) olvState . ColumnWidths [ i ] ;
column . IsVisible = ( bool ) olvState . ColumnIsVisible [ i ] ;
column . LastDisplayIndex = ( int ) olvState . ColumnDisplayIndicies [ i ] ;
}
// ReSharper disable RedundantCheckBeforeAssignment
if ( olvState . IsShowingGroups ! = this . ShowGroups )
// ReSharper restore RedundantCheckBeforeAssignment
this . ShowGroups = olvState . IsShowingGroups ;
if ( this . View = = olvState . CurrentView )
this . RebuildColumns ( ) ;
else
this . View = olvState . CurrentView ;
}
return true ;
}
/// <summary>
/// Instances of this class are used to store the state of an ObjectListView.
/// </summary>
[Serializable]
internal class ObjectListViewState
{
// ReSharper disable NotAccessedField.Global
public int VersionNumber = 1 ;
// ReSharper restore NotAccessedField.Global
public int NumberOfColumns = 1 ;
public View CurrentView ;
public int SortColumn = - 1 ;
public bool IsShowingGroups ;
public SortOrder LastSortOrder = SortOrder . None ;
// ReSharper disable FieldCanBeMadeReadOnly.Global
public ArrayList ColumnIsVisible = new ArrayList ( ) ;
public ArrayList ColumnDisplayIndicies = new ArrayList ( ) ;
public ArrayList ColumnWidths = new ArrayList ( ) ;
// ReSharper restore FieldCanBeMadeReadOnly.Global
}
#endregion
#region Event handlers
/// <summary>
/// The application is idle. Trigger a SelectionChanged event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void HandleApplicationIdle ( object sender , EventArgs e ) {
// Remove the handler before triggering the event
Application . Idle - = new EventHandler ( HandleApplicationIdle ) ;
this . hasIdleHandler = false ;
this . OnSelectionChanged ( new EventArgs ( ) ) ;
}
/// <summary>
/// The application is idle. Handle the column resizing event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void HandleApplicationIdleResizeColumns ( object sender , EventArgs e ) {
// Remove the handler before triggering the event
Application . Idle - = new EventHandler ( this . HandleApplicationIdleResizeColumns ) ;
this . hasResizeColumnsHandler = false ;
this . ResizeFreeSpaceFillingColumns ( ) ;
}
/// <summary>
/// Handle the BeginScroll listview notification
/// </summary>
/// <param name="m"></param>
/// <returns>True if the event was completely handled</returns>
protected virtual bool HandleBeginScroll ( ref Message m ) {
//System.Diagnostics.Debug.WriteLine("LVN_BEGINSCROLL");
NativeMethods . NMLVSCROLL nmlvscroll = ( NativeMethods . NMLVSCROLL ) m . GetLParam ( typeof ( NativeMethods . NMLVSCROLL ) ) ;
if ( nmlvscroll . dx ! = 0 ) {
int scrollPositionH = NativeMethods . GetScrollPosition ( this , true ) ;
ScrollEventArgs args = new ScrollEventArgs ( ScrollEventType . EndScroll , scrollPositionH - nmlvscroll . dx , scrollPositionH , ScrollOrientation . HorizontalScroll ) ;
this . OnScroll ( args ) ;
// Force any empty list msg to redraw when the list is scrolled horizontally
if ( this . GetItemCount ( ) = = 0 )
this . Invalidate ( ) ;
}
if ( nmlvscroll . dy ! = 0 ) {
int scrollPositionV = NativeMethods . GetScrollPosition ( this , false ) ;
ScrollEventArgs args = new ScrollEventArgs ( ScrollEventType . EndScroll , scrollPositionV - nmlvscroll . dy , scrollPositionV , ScrollOrientation . VerticalScroll ) ;
this . OnScroll ( args ) ;
}
return false ;
}
/// <summary>
/// Handle the EndScroll listview notification
/// </summary>
/// <param name="m"></param>
/// <returns>True if the event was completely handled</returns>
protected virtual bool HandleEndScroll ( ref Message m ) {
//System.Diagnostics.Debug.WriteLine("LVN_BEGINSCROLL");
// There is a bug in ListView under XP that causes the gridlines to be incorrectly scrolled
// when the left button is clicked to scroll. This is supposedly documented at
// KB 813791, but I couldn't find it anywhere. You can follow this thread to see the discussion
// http://www.ureader.com/msg/1484143.aspx
if ( ! ObjectListView . IsVistaOrLater & & ObjectListView . IsLeftMouseDown & & this . GridLines ) {
this . Invalidate ( ) ;
this . Update ( ) ;
}
return false ;
}
/// <summary>
/// Handle the LinkClick listview notification
/// </summary>
/// <param name="m"></param>
/// <returns>True if the event was completely handled</returns>
protected virtual bool HandleLinkClick ( ref Message m ) {
//System.Diagnostics.Debug.WriteLine("HandleLinkClick");
NativeMethods . NMLVLINK nmlvlink = ( NativeMethods . NMLVLINK ) m . GetLParam ( typeof ( NativeMethods . NMLVLINK ) ) ;
// Find the group that was clicked and trigger an event
foreach ( OLVGroup x in this . OLVGroups ) {
if ( x . GroupId = = nmlvlink . iSubItem ) {
this . OnGroupTaskClicked ( new GroupTaskClickedEventArgs ( x ) ) ;
return true ;
}
}
return false ;
}
/// <summary>
/// The cell tooltip control wants information about the tool tip that it should show.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void HandleCellToolTipShowing ( object sender , ToolTipShowingEventArgs e ) {
this . BuildCellEvent ( e , this . PointToClient ( Cursor . Position ) ) ;
if ( e . Item ! = null ) {
e . Text = this . GetCellToolTip ( e . ColumnIndex , e . RowIndex ) ;
this . OnCellToolTip ( e ) ;
}
}
/// <summary>
/// Allow the HeaderControl to call back into HandleHeaderToolTipShowing without making that method public
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
internal void HeaderToolTipShowingCallback ( object sender , ToolTipShowingEventArgs e ) {
this . HandleHeaderToolTipShowing ( sender , e ) ;
}
/// <summary>
/// The header tooltip control wants information about the tool tip that it should show.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void HandleHeaderToolTipShowing ( object sender , ToolTipShowingEventArgs e ) {
e . ColumnIndex = this . HeaderControl . ColumnIndexUnderCursor ;
if ( e . ColumnIndex < 0 )
return ;
e . RowIndex = - 1 ;
e . Model = null ;
e . Column = this . GetColumn ( e . ColumnIndex ) ;
e . Text = this . GetHeaderToolTip ( e . ColumnIndex ) ;
e . ListView = this ;
this . OnHeaderToolTip ( e ) ;
}
/// <summary>
/// Event handler for the column click event
/// </summary>
protected virtual void HandleColumnClick ( object sender , ColumnClickEventArgs e ) {
if ( ! this . PossibleFinishCellEditing ( ) )
return ;
// Toggle the sorting direction on successive clicks on the same column
if ( this . PrimarySortColumn ! = null & & e . Column = = this . PrimarySortColumn . Index )
this . PrimarySortOrder = ( this . PrimarySortOrder = = SortOrder . Descending ? SortOrder . Ascending : SortOrder . Descending ) ;
else
this . PrimarySortOrder = SortOrder . Ascending ;
this . BeginUpdate ( ) ;
try {
this . Sort ( e . Column ) ;
} finally {
this . EndUpdate ( ) ;
}
}
#endregion
#region Low level Windows Message handling
/// <summary>
/// Override the basic message pump for this control
/// </summary>
/// <param name="m"></param>
protected override void WndProc ( ref Message m )
{
// System.Diagnostics.Debug.WriteLine(m.Msg);
switch ( m . Msg ) {
case 2 : // WM_DESTROY
if ( ! this . HandleDestroy ( ref m ) )
base . WndProc ( ref m ) ;
break ;
//case 0x14: // WM_ERASEBKGND
// Can't do anything here since, when the control is double buffered, anything
// done here is immediately over-drawn
// break;
case 0x0F : // WM_PAINT
if ( ! this . HandlePaint ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x46 : // WM_WINDOWPOSCHANGING
if ( this . PossibleFinishCellEditing ( ) & & ! this . HandleWindowPosChanging ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x4E : // WM_NOTIFY
if ( ! this . HandleNotify ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x0100 : // WM_KEY_DOWN
if ( ! this . HandleKeyDown ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x0102 : // WM_CHAR
if ( ! this . HandleChar ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x0200 : // WM_MOUSEMOVE
if ( ! this . HandleMouseMove ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x0201 : // WM_LBUTTONDOWN
if ( this . PossibleFinishCellEditing ( ) & & ! this . HandleLButtonDown ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x202 : // WM_LBUTTONUP
if ( this . PossibleFinishCellEditing ( ) & & ! this . HandleLButtonUp ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x0203 : // WM_LBUTTONDBLCLK
if ( this . PossibleFinishCellEditing ( ) & & ! this . HandleLButtonDoubleClick ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x0204 : // WM_RBUTTONDOWN
if ( this . PossibleFinishCellEditing ( ) & & ! this . HandleRButtonDown ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x0206 : // WM_RBUTTONDBLCLK
if ( this . PossibleFinishCellEditing ( ) & & ! this . HandleRButtonDoubleClick ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x204E : // WM_REFLECT_NOTIFY
if ( ! this . HandleReflectNotify ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x114 : // WM_HSCROLL:
case 0x115 : // WM_VSCROLL:
//System.Diagnostics.Debug.WriteLine("WM_VSCROLL");
if ( this . PossibleFinishCellEditing ( ) )
base . WndProc ( ref m ) ;
break ;
case 0x20A : // WM_MOUSEWHEEL:
case 0x20E : // WM_MOUSEHWHEEL:
if ( this . PossibleFinishCellEditing ( ) )
base . WndProc ( ref m ) ;
break ;
case 0x7B : // WM_CONTEXTMENU
if ( ! this . HandleContextMenu ( ref m ) )
base . WndProc ( ref m ) ;
break ;
case 0x1000 + 18 : // LVM_HITTEST:
//System.Diagnostics.Debug.WriteLine("LVM_HITTEST");
if ( this . skipNextHitTest ) {
//System.Diagnostics.Debug.WriteLine("SKIPPING LVM_HITTEST");
this . skipNextHitTest = false ;
} else {
base . WndProc ( ref m ) ;
}
break ;
default :
base . WndProc ( ref m ) ;
break ;
}
}
/// <summary>
/// Handle the search for item m if possible.
/// </summary>
/// <param name="m">The m to be processed</param>
/// <returns>bool to indicate if the msg has been handled</returns>
protected virtual bool HandleChar ( ref Message m ) {
// Trigger a normal KeyPress event, which listeners can handle if they want.
// Handling the event stops ObjectListView's fancy search-by-typing.
if ( this . ProcessKeyEventArgs ( ref m ) )
return true ;
const int MILLISECONDS_BETWEEN_KEYPRESSES = 1000 ;
// What character did the user type and was it part of a longer string?
char character = ( char ) m . WParam . ToInt32 ( ) ; //TODO: Will this work on 64 bit or MBCS?
if ( character = = ( char ) Keys . Back ) {
// Backspace forces the next key to be considered the start of a new search
this . timeLastCharEvent = 0 ;
return true ;
}
if ( System . Environment . TickCount < ( this . timeLastCharEvent + MILLISECONDS_BETWEEN_KEYPRESSES ) )
this . lastSearchString + = character ;
else
this . lastSearchString = character . ToString ( CultureInfo . InvariantCulture ) ;
// If this control is showing checkboxes, we want to ignore single space presses,
// since they are used to toggle the selected checkboxes.
if ( this . CheckBoxes & & this . lastSearchString = = " " ) {
this . timeLastCharEvent = 0 ;
return true ;
}
// Where should the search start?
int start = 0 ;
ListViewItem focused = this . FocusedItem ;
if ( focused ! = null ) {
start = this . GetDisplayOrderOfItemIndex ( focused . Index ) ;
// If the user presses a single key, we search from after the focused item,
// being careful not to march past the end of the list
if ( this . lastSearchString . Length = = 1 ) {
start + = 1 ;
if ( start = = this . GetItemCount ( ) )
start = 0 ;
}
}
// Give the world a chance to fiddle with or completely avoid the searching process
BeforeSearchingEventArgs args = new BeforeSearchingEventArgs ( this . lastSearchString , start ) ;
this . OnBeforeSearching ( args ) ;
if ( args . Canceled )
return true ;
// The parameters of the search may have been changed
string searchString = args . StringToFind ;
start = args . StartSearchFrom ;
// Do the actual search
int found = this . FindMatchingRow ( searchString , start , SearchDirectionHint . Down ) ;
if ( found > = 0 ) {
// Select and focus on the found item
this . BeginUpdate ( ) ;
try {
this . SelectedIndices . Clear ( ) ;
OLVListItem lvi = this . GetNthItemInDisplayOrder ( found ) ;
if ( lvi ! = null ) {
if ( lvi . Enabled )
lvi . Selected = true ;
lvi . Focused = true ;
this . EnsureVisible ( lvi . Index ) ;
}
} finally {
this . EndUpdate ( ) ;
}
}
// Tell the world that a search has occurred
AfterSearchingEventArgs args2 = new AfterSearchingEventArgs ( searchString , found ) ;
this . OnAfterSearching ( args2 ) ;
if ( ! args2 . Handled ) {
if ( found < 0 )
System . Media . SystemSounds . Beep . Play ( ) ;
}
// When did this event occur?
this . timeLastCharEvent = System . Environment . TickCount ;
return true ;
}
private int timeLastCharEvent ;
private string lastSearchString ;
/// <summary>
/// The user wants to see the context menu.
/// </summary>
/// <param name="m">The windows m</param>
/// <returns>A bool indicating if this m has been handled</returns>
/// <remarks>
/// We want to ignore context menu requests that are triggered by right clicks on the header
/// </remarks>
protected virtual bool HandleContextMenu ( ref Message m ) {
// Don't try to handle context menu commands at design time.
if ( this . DesignMode )
return false ;
// If the context menu command was generated by the keyboard, LParam will be -1.
// We don't want to process these.
if ( m . LParam = = this . minusOne )
return false ;
// If the context menu came from somewhere other than the header control,
// we also don't want to ignore it
if ( m . WParam ! = this . HeaderControl . Handle )
return false ;
// OK. Looks like a right click in the header
if ( ! this . PossibleFinishCellEditing ( ) )
return true ;
int columnIndex = this . HeaderControl . ColumnIndexUnderCursor ;
return this . HandleHeaderRightClick ( columnIndex ) ;
}
readonly IntPtr minusOne = new IntPtr ( - 1 ) ;
/// <summary>
/// Handle the Custom draw series of notifications
/// </summary>
/// <param name="m">The message</param>
/// <returns>True if the message has been handled</returns>
protected virtual bool HandleCustomDraw ( ref Message m ) {
const int CDDS_PREPAINT = 1 ;
const int CDDS_POSTPAINT = 2 ;
const int CDDS_PREERASE = 3 ;
const int CDDS_POSTERASE = 4 ;
//const int CDRF_NEWFONT = 2;
//const int CDRF_SKIPDEFAULT = 4;
const int CDDS_ITEM = 0x00010000 ;
const int CDDS_SUBITEM = 0x00020000 ;
const int CDDS_ITEMPREPAINT = ( CDDS_ITEM | CDDS_PREPAINT ) ;
const int CDDS_ITEMPOSTPAINT = ( CDDS_ITEM | CDDS_POSTPAINT ) ;
const int CDDS_ITEMPREERASE = ( CDDS_ITEM | CDDS_PREERASE ) ;
const int CDDS_ITEMPOSTERASE = ( CDDS_ITEM | CDDS_POSTERASE ) ;
const int CDDS_SUBITEMPREPAINT = ( CDDS_SUBITEM | CDDS_ITEMPREPAINT ) ;
const int CDDS_SUBITEMPOSTPAINT = ( CDDS_SUBITEM | CDDS_ITEMPOSTPAINT ) ;
const int CDRF_NOTIFYPOSTPAINT = 0x10 ;
//const int CDRF_NOTIFYITEMDRAW = 0x20;
//const int CDRF_NOTIFYSUBITEMDRAW = 0x20; // same value as above!
const int CDRF_NOTIFYPOSTERASE = 0x40 ;
// There is a bug in owner drawn virtual lists which causes lots of custom draw messages
// to be sent to the control *outside* of a WmPaint event. AFAIK, these custom draw events
// are spurious and only serve to make the control flicker annoyingly.
// So, we ignore messages that are outside of a paint event.
if ( ! this . isInWmPaintEvent )
return true ;
// One more complication! Sometimes with owner drawn virtual lists, the act of drawing
// the overlays triggers a second attempt to paint the control -- which makes an annoying
// flicker. So, we only do the custom drawing once per WmPaint event.
if ( ! this . shouldDoCustomDrawing )
return true ;
NativeMethods . NMLVCUSTOMDRAW nmcustomdraw = ( NativeMethods . NMLVCUSTOMDRAW ) m . GetLParam ( typeof ( NativeMethods . NMLVCUSTOMDRAW ) ) ;
//System.Diagnostics.Debug.WriteLine(String.Format("cd: {0:x}, {1}, {2}", nmcustomdraw.nmcd.dwDrawStage, nmcustomdraw.dwItemType, nmcustomdraw.nmcd.dwItemSpec));
// Ignore drawing of group items
if ( nmcustomdraw . dwItemType = = 1 ) {
// This is the basis of an idea about how to owner draw group headers
//nmcustomdraw.clrText = ColorTranslator.ToWin32(Color.DeepPink);
//nmcustomdraw.clrFace = ColorTranslator.ToWin32(Color.DeepPink);
//nmcustomdraw.clrTextBk = ColorTranslator.ToWin32(Color.DeepPink);
//Marshal.StructureToPtr(nmcustomdraw, m.LParam, false);
//using (Graphics g = Graphics.FromHdc(nmcustomdraw.nmcd.hdc)) {
// g.DrawRectangle(Pens.Red, Rectangle.FromLTRB(nmcustomdraw.rcText.left, nmcustomdraw.rcText.top, nmcustomdraw.rcText.right, nmcustomdraw.rcText.bottom));
//}
//m.Result = (IntPtr)((int)m.Result | CDRF_SKIPDEFAULT);
return true ;
}
switch ( nmcustomdraw . nmcd . dwDrawStage ) {
case CDDS_PREPAINT :
//System.Diagnostics.Debug.WriteLine("CDDS_PREPAINT");
// Remember which items were drawn during this paint cycle
if ( this . prePaintLevel = = 0 )
this . drawnItems = new List < OLVListItem > ( ) ;
// If there are any items, we have to wait until at least one has been painted
// before we draw the overlays. If there aren't any items, there will never be any
// item paint events, so we can draw the overlays whenever
this . isAfterItemPaint = ( this . GetItemCount ( ) = = 0 ) ;
this . prePaintLevel + + ;
base . WndProc ( ref m ) ;
// Make sure that we get postpaint notifications
m . Result = ( IntPtr ) ( ( int ) m . Result | CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYPOSTERASE ) ;
return true ;
case CDDS_POSTPAINT :
//System.Diagnostics.Debug.WriteLine("CDDS_POSTPAINT");
this . prePaintLevel - - ;
// When in group view, we have two problems. On XP, the control sends
// a whole heap of PREPAINT/POSTPAINT messages before drawing any items.
// We have to wait until after the first item paint before we draw overlays.
// On Vista, we have a different problem. On Vista, the control nests calls
// to PREPAINT and POSTPAINT. We only want to draw overlays on the outermost
// POSTPAINT.
if ( this . prePaintLevel = = 0 & & ( this . isMarqueSelecting | | this . isAfterItemPaint ) ) {
this . shouldDoCustomDrawing = false ;
// Draw our overlays after everything has been drawn
using ( Graphics g = Graphics . FromHdc ( nmcustomdraw . nmcd . hdc ) ) {
this . DrawAllDecorations ( g , this . drawnItems ) ;
}
}
break ;
case CDDS_ITEMPREPAINT :
//System.Diagnostics.Debug.WriteLine("CDDS_ITEMPREPAINT");
// When in group view on XP, the control send a whole heap of PREPAINT/POSTPAINT
// messages before drawing any items.
// We have to wait until after the first item paint before we draw overlays
this . isAfterItemPaint = true ;
// This scheme of catching custom draw msgs works fine, except
// for Tile view. Something in .NET's handling of Tile view causes lots
// of invalidates and erases. So, we just ignore completely
// .NET's handling of Tile view and let the underlying control
// do its stuff. Strangely, if the Tile view is
// completely owner drawn, those erasures don't happen.
if ( this . View = = View . Tile ) {
if ( this . OwnerDraw & & this . ItemRenderer ! = null )
base . WndProc ( ref m ) ;
} else {
base . WndProc ( ref m ) ;
}
m . Result = ( IntPtr ) ( ( int ) m . Result | CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYPOSTERASE ) ;
return true ;
case CDDS_ITEMPOSTPAINT :
//System.Diagnostics.Debug.WriteLine("CDDS_ITEMPOSTPAINT");
// Remember which items have been drawn so we can draw any decorations for them
// once all other painting is finished
if ( this . Columns . Count > 0 ) {
OLVListItem olvi = this . GetItem ( ( int ) nmcustomdraw . nmcd . dwItemSpec ) ;
if ( olvi ! = null )
this . drawnItems . Add ( olvi ) ;
}
break ;
case CDDS_SUBITEMPREPAINT :
//System.Diagnostics.Debug.WriteLine(String.Format("CDDS_SUBITEMPREPAINT ({0},{1})", (int)nmcustomdraw.nmcd.dwItemSpec, nmcustomdraw.iSubItem));
// There is a bug in the .NET framework which appears when column 0 of an owner drawn listview
// is dragged to another column position.
// The bounds calculation always returns the left edge of column 0 as being 0.
// The effects of this bug become apparent
// when the listview is scrolled horizontally: the control can think that column 0
// is no longer visible (the horizontal scroll position is subtracted from the bounds, giving a
// rectangle that is offscreen). In those circumstances, column 0 is not redraw because
// the control thinks it is not visible and so does not trigger a DrawSubItem event.
// To fix this problem, we have to detected the situation -- owner drawing column 0 in any column except 0 --
// trigger our own DrawSubItem, and then prevent the default processing from occuring.
// Are we owner drawing column 0 when it's in any column except 0?
if ( ! this . OwnerDraw )
return false ;
int columnIndex = nmcustomdraw . iSubItem ;
if ( columnIndex ! = 0 )
return false ;
int displayIndex = this . Columns [ 0 ] . DisplayIndex ;
if ( displayIndex = = 0 )
return false ;
int rowIndex = ( int ) nmcustomdraw . nmcd . dwItemSpec ;
OLVListItem item = this . GetItem ( rowIndex ) ;
if ( item = = null )
return false ;
// OK. We have the error condition, so lets do what the .NET framework should do.
// Trigger an event to draw column 0 when it is not at display index 0
using ( Graphics g = Graphics . FromHdc ( nmcustomdraw . nmcd . hdc ) ) {
// Correctly calculate the bounds of cell 0
Rectangle r = item . GetSubItemBounds ( 0 ) ;
// We can hardcode "0" here since we know we are only doing this for column 0
DrawListViewSubItemEventArgs args = new DrawListViewSubItemEventArgs ( g , r , item , item . SubItems [ 0 ] , rowIndex , 0 ,
this . Columns [ 0 ] , ( ListViewItemStates ) nmcustomdraw . nmcd . uItemState ) ;
this . OnDrawSubItem ( args ) ;
// If the event handler wants to do the default processing (i.e. DrawDefault = true), we are stuck.
// There is no way we can force the default drawing because of the bug in .NET we are trying to get around.
System . Diagnostics . Trace . Assert ( ! args . DrawDefault , "Default drawing is impossible in this situation" ) ;
}
m . Result = ( IntPtr ) 4 ;
return true ;
case CDDS_SUBITEMPOSTPAINT :
//System.Diagnostics.Debug.WriteLine("CDDS_SUBITEMPOSTPAINT");
break ;
// I have included these stages, but it doesn't seem that they are sent for ListViews.
// http://www.tech-archive.net/Archive/VC/microsoft.public.vc.mfc/2006-08/msg00220.html
case CDDS_PREERASE :
//System.Diagnostics.Debug.WriteLine("CDDS_PREERASE");
break ;
case CDDS_POSTERASE :
//System.Diagnostics.Debug.WriteLine("CDDS_POSTERASE");
break ;
case CDDS_ITEMPREERASE :
//System.Diagnostics.Debug.WriteLine("CDDS_ITEMPREERASE");
break ;
case CDDS_ITEMPOSTERASE :
//System.Diagnostics.Debug.WriteLine("CDDS_ITEMPOSTERASE");
break ;
}
return false ;
}
bool isAfterItemPaint ;
List < OLVListItem > drawnItems ;
/// <summary>
/// Handle the underlying control being destroyed
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
protected virtual bool HandleDestroy ( ref Message m ) {
//System.Diagnostics.Debug.WriteLine(String.Format("WM_DESTROY: Disposing={0}, IsDisposed={1}, VirtualMode={2}", Disposing, IsDisposed, VirtualMode));
// Recreate the header control when the listview control is destroyed
this . headerControl = null ;
// When the underlying control is destroyed, we need to recreate and reconfigure its tooltip
if ( this . cellToolTip ! = null ) {
this . cellToolTip . PushSettings ( ) ;
this . BeginInvoke ( ( MethodInvoker ) delegate {
this . UpdateCellToolTipHandle ( ) ;
this . cellToolTip . PopSettings ( ) ;
} ) ;
}
return false ;
}
/// <summary>
/// Handle the search for item m if possible.
/// </summary>
/// <param name="m">The m to be processed</param>
/// <returns>bool to indicate if the msg has been handled</returns>
protected virtual bool HandleFindItem ( ref Message m ) {
// NOTE: As far as I can see, this message is never actually sent to the control, making this
// method redundant!
const int LVFI_STRING = 0x0002 ;
NativeMethods . LVFINDINFO findInfo = ( NativeMethods . LVFINDINFO ) m . GetLParam ( typeof ( NativeMethods . LVFINDINFO ) ) ;
// We can only handle string searches
if ( ( findInfo . flags & LVFI_STRING ) ! = LVFI_STRING )
return false ;
int start = m . WParam . ToInt32 ( ) ;
m . Result = ( IntPtr ) this . FindMatchingRow ( findInfo . psz , start , SearchDirectionHint . Down ) ;
return true ;
}
/// <summary>
/// Find the first row after the given start in which the text value in the
/// comparison column begins with the given text. The comparison column is column 0,
/// unless IsSearchOnSortColumn is true, in which case the current sort column is used.
/// </summary>
/// <param name="text">The text to be prefix matched</param>
/// <param name="start">The index of the first row to consider</param>
/// <param name="direction">Which direction should be searched?</param>
/// <returns>The index of the first row that matched, or -1</returns>
/// <remarks>The text comparison is a case-insensitive, prefix match. The search will
/// search the every row until a match is found, wrapping at the end if needed.</remarks>
public virtual int FindMatchingRow ( string text , int start , SearchDirectionHint direction ) {
// We also can't do anything if we don't have data
int rowCount = this . GetItemCount ( ) ;
if ( rowCount = = 0 )
return - 1 ;
// Which column are we going to use for our comparing?
OLVColumn column = this . GetColumn ( 0 ) ;
if ( this . IsSearchOnSortColumn & & this . View = = View . Details & & this . PrimarySortColumn ! = null )
column = this . PrimarySortColumn ;
// Do two searches if necessary to find a match. The second search is the wrap-around part of searching
int i ;
if ( direction = = SearchDirectionHint . Down ) {
i = this . FindMatchInRange ( text , start , rowCount - 1 , column ) ;
if ( i = = - 1 & & start > 0 )
i = this . FindMatchInRange ( text , 0 , start - 1 , column ) ;
} else {
i = this . FindMatchInRange ( text , start , 0 , column ) ;
if ( i = = - 1 & & start ! = rowCount )
i = this . FindMatchInRange ( text , rowCount - 1 , start + 1 , column ) ;
}
return i ;
}
/// <summary>
/// Find the first row in the given range of rows that prefix matches the string value of the given column.
/// </summary>
/// <param name="text"></param>
/// <param name="first"></param>
/// <param name="last"></param>
/// <param name="column"></param>
/// <returns>The index of the matched row, or -1</returns>
protected virtual int FindMatchInRange ( string text , int first , int last , OLVColumn column ) {
if ( first < = last ) {
for ( int i = first ; i < = last ; i + + ) {
string data = column . GetStringValue ( this . GetNthItemInDisplayOrder ( i ) . RowObject ) ;
if ( data . StartsWith ( text , StringComparison . CurrentCultureIgnoreCase ) )
return i ;
}
} else {
for ( int i = first ; i > = last ; i - - ) {
string data = column . GetStringValue ( this . GetNthItemInDisplayOrder ( i ) . RowObject ) ;
if ( data . StartsWith ( text , StringComparison . CurrentCultureIgnoreCase ) )
return i ;
}
}
return - 1 ;
}
/// <summary>
/// Handle the Group Info series of notifications
/// </summary>
/// <param name="m">The message</param>
/// <returns>True if the message has been handled</returns>
protected virtual bool HandleGroupInfo ( ref Message m )
{
NativeMethods . NMLVGROUP nmlvgroup = ( NativeMethods . NMLVGROUP ) m . GetLParam ( typeof ( NativeMethods . NMLVGROUP ) ) ;
//System.Diagnostics.Debug.WriteLine(String.Format("group: {0}, old state: {1}, new state: {2}",
// nmlvgroup.iGroupId, OLVGroup.StateToString(nmlvgroup.uOldState), OLVGroup.StateToString(nmlvgroup.uNewState)));
// Ignore state changes that aren't related to selection, focus or collapsedness
const uint INTERESTING_STATES = ( uint ) ( GroupState . LVGS_COLLAPSED | GroupState . LVGS_FOCUSED | GroupState . LVGS_SELECTED ) ;
if ( ( nmlvgroup . uOldState & INTERESTING_STATES ) = = ( nmlvgroup . uNewState & INTERESTING_STATES ) )
return false ;
foreach ( OLVGroup group in this . OLVGroups ) {
if ( group . GroupId = = nmlvgroup . iGroupId ) {
GroupStateChangedEventArgs args = new GroupStateChangedEventArgs ( group , ( GroupState ) nmlvgroup . uOldState , ( GroupState ) nmlvgroup . uNewState ) ;
this . OnGroupStateChanged ( args ) ;
break ;
}
}
return false ;
}
//private static string StateToString(uint state)
//{
// if (state == 0)
// return Enum.GetName(typeof(GroupState), 0);
// List<string> names = new List<string>();
// foreach (int value in Enum.GetValues(typeof(GroupState)))
// {
// if (value != 0 && (state & value) == value)
// {
// names.Add(Enum.GetName(typeof(GroupState), value));
// }
// }
// return names.Count == 0 ? state.ToString("x") : String.Join("|", names.ToArray());
//}
/// <summary>
/// Handle a key down message
/// </summary>
/// <param name="m"></param>
/// <returns>True if the msg has been handled</returns>
protected virtual bool HandleKeyDown ( ref Message m ) {
// If this is a checkbox list, toggle the selected rows when the user presses Space
if ( this . CheckBoxes & & m . WParam . ToInt32 ( ) = = ( int ) Keys . Space & & this . SelectedIndices . Count > 0 ) {
this . ToggleSelectedRowCheckBoxes ( ) ;
return true ;
}
// Remember the scroll position so we can decide if the listview has scrolled in the
// handling of the event.
int scrollPositionH = NativeMethods . GetScrollPosition ( this , true ) ;
int scrollPositionV = NativeMethods . GetScrollPosition ( this , false ) ;
base . WndProc ( ref m ) ;
// It's possible that the processing in base.WndProc has actually destroyed this control
if ( this . IsDisposed )
return true ;
// If the keydown processing changed the scroll position, trigger a Scroll event
int newScrollPositionH = NativeMethods . GetScrollPosition ( this , true ) ;
int newScrollPositionV = NativeMethods . GetScrollPosition ( this , false ) ;
if ( scrollPositionH ! = newScrollPositionH ) {
ScrollEventArgs args = new ScrollEventArgs ( ScrollEventType . EndScroll ,
scrollPositionH , newScrollPositionH , ScrollOrientation . HorizontalScroll ) ;
this . OnScroll ( args ) ;
}
if ( scrollPositionV ! = newScrollPositionV ) {
ScrollEventArgs args = new ScrollEventArgs ( ScrollEventType . EndScroll ,
scrollPositionV , newScrollPositionV , ScrollOrientation . VerticalScroll ) ;
this . OnScroll ( args ) ;
}
if ( scrollPositionH ! = newScrollPositionH | | scrollPositionV ! = newScrollPositionV )
this . RefreshHotItem ( ) ;
return true ;
}
/// <summary>
/// Toggle the checkedness of the selected rows
/// </summary>
/// <remarks>
/// <para>
/// Actually, this doesn't actually toggle all rows. It toggles the first row, and
/// all other rows get the check state of that first row. This is actually a much
/// more useful behaviour.
/// </para>
/// <para>
/// If no rows are selected, this method does nothing.
/// </para>
/// </remarks>
public void ToggleSelectedRowCheckBoxes ( ) {
if ( this . SelectedIndices . Count = = 0 )
return ;
Object primaryModel = this . GetItem ( this . SelectedIndices [ 0 ] ) . RowObject ;
this . ToggleCheckObject ( primaryModel ) ;
CheckState ? state = this . GetCheckState ( primaryModel ) ;
if ( state . HasValue ) {
foreach ( Object x in this . SelectedObjects )
this . SetObjectCheckedness ( x , state . Value ) ;
}
}
/// <summary>
/// Catch the Left Button down event.
/// </summary>
/// <param name="m">The m to be processed</param>
/// <returns>bool to indicate if the msg has been handled</returns>
protected virtual bool HandleLButtonDown ( ref Message m ) {
// We have to intercept this low level message rather than the more natural
// overridding of OnMouseDown, since ListCtrl's internal mouse down behavior
// is to select (or deselect) rows when the mouse is released. We don't
// want the selection to change when the user checks or unchecks a checkbox, so if the
// mouse down event was to check/uncheck, we have to hide this mouse
// down event from the control.
int x = m . LParam . ToInt32 ( ) & 0xFFFF ;
int y = ( m . LParam . ToInt32 ( ) > > 16 ) & 0xFFFF ;
return this . ProcessLButtonDown ( this . OlvHitTest ( x , y ) ) ;
}
/// <summary>
/// Handle a left mouse down at the given hit test location
/// </summary>
/// <remarks>Subclasses can override this to do something unique</remarks>
/// <param name="hti"></param>
/// <returns>True if the message has been handled</returns>
protected virtual bool ProcessLButtonDown ( OlvListViewHitTestInfo hti ) {
if ( hti . Item = = null )
return false ;
// If the click occurs on a button, ignore it so the row isn't selected
if ( hti . HitTestLocation = = HitTestLocation . Button ) {
this . Invalidate ( ) ;
return true ;
}
// If they didn't click checkbox, we can just return
if ( hti . HitTestLocation ! = HitTestLocation . CheckBox )
return false ;
// Disabled rows cannot change checkboxes
if ( ! hti . Item . Enabled )
return true ;
// Did they click a sub item checkbox?
if ( hti . Column ! = null & & hti . Column . Index > 0 ) {
if ( hti . Column . IsEditable & & hti . Item . Enabled )
this . ToggleSubItemCheckBox ( hti . RowObject , hti . Column ) ;
return true ;
}
// They must have clicked the primary checkbox
this . ToggleCheckObject ( hti . RowObject ) ;
// If they change the checkbox of a selected row, all the rows in the selection
// should be given the same state
if ( hti . Item . Selected ) {
CheckState ? state = this . GetCheckState ( hti . RowObject ) ;
if ( state . HasValue ) {
foreach ( Object x in this . SelectedObjects )
this . SetObjectCheckedness ( x , state . Value ) ;
}
}
return true ;
}
/// <summary>
/// Catch the Left Button up event.
/// </summary>
/// <param name="m">The m to be processed</param>
/// <returns>bool to indicate if the msg has been handled</returns>
protected virtual bool HandleLButtonUp ( ref Message m ) {
if ( this . MouseMoveHitTest = = null )
return false ;
int x = m . LParam . ToInt32 ( ) & 0xFFFF ;
int y = ( m . LParam . ToInt32 ( ) > > 16 ) & 0xFFFF ;
// Did they click an enabled, non-empty button?
if ( this . MouseMoveHitTest . HitTestLocation = = HitTestLocation . Button ) {
// If a button was hit, Item and Column must be non-null
if ( this . MouseMoveHitTest . Item . Enabled | | this . MouseMoveHitTest . Column . EnableButtonWhenItemIsDisabled ) {
string buttonText = this . MouseMoveHitTest . Column . GetStringValue ( this . MouseMoveHitTest . RowObject ) ;
if ( ! String . IsNullOrEmpty ( buttonText ) ) {
this . Invalidate ( ) ;
CellClickEventArgs args = new CellClickEventArgs ( ) ;
this . BuildCellEvent ( args , new Point ( x , y ) , this . MouseMoveHitTest ) ;
this . OnButtonClick ( args ) ;
return true ;
}
}
}
// Are they trying to expand/collapse a group?
if ( this . MouseMoveHitTest . HitTestLocation = = HitTestLocation . GroupExpander ) {
if ( this . TriggerGroupExpandCollapse ( this . MouseMoveHitTest . Group ) )
return true ;
}
if ( ObjectListView . IsVistaOrLater & & this . HasCollapsibleGroups )
base . DefWndProc ( ref m ) ;
return false ;
}
/// <summary>
/// Trigger a GroupExpandCollapse event and return true if the action was cancelled
/// </summary>
/// <param name="group"></param>
/// <returns></returns>
protected virtual bool TriggerGroupExpandCollapse ( OLVGroup group )
{
GroupExpandingCollapsingEventArgs args = new GroupExpandingCollapsingEventArgs ( group ) ;
this . OnGroupExpandingCollapsing ( args ) ;
return args . Canceled ;
}
/// <summary>
/// Catch the Right Button down event.
/// </summary>
/// <param name="m">The m to be processed</param>
/// <returns>bool to indicate if the msg has been handled</returns>
protected virtual bool HandleRButtonDown ( ref Message m ) {
int x = m . LParam . ToInt32 ( ) & 0xFFFF ;
int y = ( m . LParam . ToInt32 ( ) > > 16 ) & 0xFFFF ;
return this . ProcessRButtonDown ( this . OlvHitTest ( x , y ) ) ;
}
/// <summary>
/// Handle a left mouse down at the given hit test location
/// </summary>
/// <remarks>Subclasses can override this to do something unique</remarks>
/// <param name="hti"></param>
/// <returns>True if the message has been handled</returns>
protected virtual bool ProcessRButtonDown ( OlvListViewHitTestInfo hti ) {
if ( hti . Item = = null )
return false ;
// Ignore clicks on checkboxes
return ( hti . HitTestLocation = = HitTestLocation . CheckBox ) ;
}
/// <summary>
/// Catch the Left Button double click event.
/// </summary>
/// <param name="m">The m to be processed</param>
/// <returns>bool to indicate if the msg has been handled</returns>
protected virtual bool HandleLButtonDoubleClick ( ref Message m ) {
int x = m . LParam . ToInt32 ( ) & 0xFFFF ;
int y = ( m . LParam . ToInt32 ( ) > > 16 ) & 0xFFFF ;
return this . ProcessLButtonDoubleClick ( this . OlvHitTest ( x , y ) ) ;
}
/// <summary>
/// Handle a mouse double click at the given hit test location
/// </summary>
/// <remarks>Subclasses can override this to do something unique</remarks>
/// <param name="hti"></param>
/// <returns>True if the message has been handled</returns>
protected virtual bool ProcessLButtonDoubleClick ( OlvListViewHitTestInfo hti ) {
// If the user double clicked on a checkbox, ignore it
return ( hti . HitTestLocation = = HitTestLocation . CheckBox ) ;
}
/// <summary>
/// Catch the right Button double click event.
/// </summary>
/// <param name="m">The m to be processed</param>
/// <returns>bool to indicate if the msg has been handled</returns>
protected virtual bool HandleRButtonDoubleClick ( ref Message m ) {
int x = m . LParam . ToInt32 ( ) & 0xFFFF ;
int y = ( m . LParam . ToInt32 ( ) > > 16 ) & 0xFFFF ;
return this . ProcessRButtonDoubleClick ( this . OlvHitTest ( x , y ) ) ;
}
/// <summary>
/// Handle a right mouse double click at the given hit test location
/// </summary>
/// <remarks>Subclasses can override this to do something unique</remarks>
/// <param name="hti"></param>
/// <returns>True if the message has been handled</returns>
protected virtual bool ProcessRButtonDoubleClick ( OlvListViewHitTestInfo hti ) {
// If the user double clicked on a checkbox, ignore it
return ( hti . HitTestLocation = = HitTestLocation . CheckBox ) ;
}
/// <summary>
/// Catch the MouseMove event.
/// </summary>
/// <param name="m">The m to be processed</param>
/// <returns>bool to indicate if the msg has been handled</returns>
protected virtual bool HandleMouseMove ( ref Message m )
{
//int x = m.LParam.ToInt32() & 0xFFFF;
//int y = (m.LParam.ToInt32() >> 16) & 0xFFFF;
//this.lastMouseMoveX = x;
//this.lastMouseMoveY = y;
return false ;
}
//private int lastMouseMoveX = -1;
//private int lastMouseMoveY = -1;
/// <summary>
/// Handle notifications that have been reflected back from the parent window
/// </summary>
/// <param name="m">The m to be processed</param>
/// <returns>bool to indicate if the msg has been handled</returns>
protected virtual bool HandleReflectNotify ( ref Message m ) {
const int NM_CLICK = - 2 ;
const int NM_DBLCLK = - 3 ;
const int NM_RDBLCLK = - 6 ;
const int NM_CUSTOMDRAW = - 12 ;
const int NM_RELEASEDCAPTURE = - 16 ;
const int LVN_FIRST = - 100 ;
const int LVN_ITEMCHANGED = LVN_FIRST - 1 ;
const int LVN_ITEMCHANGING = LVN_FIRST - 0 ;
const int LVN_HOTTRACK = LVN_FIRST - 21 ;
const int LVN_MARQUEEBEGIN = LVN_FIRST - 56 ;
const int LVN_GETINFOTIP = LVN_FIRST - 58 ;
const int LVN_GETDISPINFO = LVN_FIRST - 77 ;
const int LVN_BEGINSCROLL = LVN_FIRST - 80 ;
const int LVN_ENDSCROLL = LVN_FIRST - 81 ;
const int LVN_LINKCLICK = LVN_FIRST - 84 ;
const int LVN_GROUPINFO = LVN_FIRST - 88 ; // undocumented
const int LVIF_STATE = 8 ;
//const int LVIS_FOCUSED = 1;
const int LVIS_SELECTED = 2 ;
bool isMsgHandled = false ;
// TODO: Don't do any logic in this method. Create separate methods for each message
NativeMethods . NMHDR nmhdr = ( NativeMethods . NMHDR ) m . GetLParam ( typeof ( NativeMethods . NMHDR ) ) ;
//System.Diagnostics.Debug.WriteLine(String.Format("rn: {0}", nmhdr->code));
switch ( nmhdr . code ) {
case NM_CLICK :
// The standard ListView does some strange stuff here when the list has checkboxes.
// If you shift click on non-primary columns when FullRowSelect is true, the
// checkedness of the selected rows changes.
// We can't just not do the base class stuff because it sets up state that is used to
// determine mouse up events later on.
// So, we sabotage the base class's process of the click event. The base class does a HITTEST
// in order to determine which row was clicked -- if that fails, the base class does nothing.
// So when we get a CLICK, we know that the base class is going to send a HITTEST very soon,
// so we ignore the next HITTEST message, which will cause the click processing to fail.
//System.Diagnostics.Debug.WriteLine("NM_CLICK");
this . skipNextHitTest = true ;
break ;
case LVN_BEGINSCROLL :
//System.Diagnostics.Debug.WriteLine("LVN_BEGINSCROLL");
isMsgHandled = this . HandleBeginScroll ( ref m ) ;
break ;
case LVN_ENDSCROLL :
isMsgHandled = this . HandleEndScroll ( ref m ) ;
break ;
case LVN_LINKCLICK :
isMsgHandled = this . HandleLinkClick ( ref m ) ;
break ;
case LVN_MARQUEEBEGIN :
//System.Diagnostics.Debug.WriteLine("LVN_MARQUEEBEGIN");
this . isMarqueSelecting = true ;
break ;
case LVN_GETINFOTIP :
//System.Diagnostics.Debug.WriteLine("LVN_GETINFOTIP");
// When virtual lists are in SmallIcon view, they generates tooltip message with invalid item indicies.
2021-06-12 14:09:28 +00:00
try
{
var lparam = m . GetLParam ( typeof ( NativeMethods . NMLVGETINFOTIP ) ) ;
NativeMethods . NMLVGETINFOTIP nmGetInfoTip = ( NativeMethods . NMLVGETINFOTIP ) lparam ;
isMsgHandled = nmGetInfoTip . iItem > = this . GetItemCount ( ) ;
}
catch { isMsgHandled = false ; }
2021-01-12 08:32:13 +00:00
break ;
case NM_RELEASEDCAPTURE :
//System.Diagnostics.Debug.WriteLine("NM_RELEASEDCAPTURE");
this . isMarqueSelecting = false ;
this . Invalidate ( ) ;
break ;
case NM_CUSTOMDRAW :
//System.Diagnostics.Debug.WriteLine("NM_CUSTOMDRAW");
isMsgHandled = this . HandleCustomDraw ( ref m ) ;
break ;
case NM_DBLCLK :
// The default behavior of a .NET ListView with checkboxes is to toggle the checkbox on
// double-click. That's just silly, if you ask me :)
if ( this . CheckBoxes ) {
// How do we make ListView not do that silliness? We could just ignore the message
// but the last part of the base code sets up state information, and without that
// state, the ListView doesn't trigger MouseDoubleClick events. So we fake a
// right button double click event, which sets up the same state, but without
// toggling the checkbox.
nmhdr . code = NM_RDBLCLK ;
Marshal . StructureToPtr ( nmhdr , m . LParam , false ) ;
}
break ;
case LVN_ITEMCHANGED :
//System.Diagnostics.Debug.WriteLine("LVN_ITEMCHANGED");
NativeMethods . NMLISTVIEW nmlistviewPtr2 = ( NativeMethods . NMLISTVIEW ) m . GetLParam ( typeof ( NativeMethods . NMLISTVIEW ) ) ;
if ( ( nmlistviewPtr2 . uChanged & LVIF_STATE ) ! = 0 ) {
CheckState currentValue = this . CalculateCheckState ( nmlistviewPtr2 . uOldState ) ;
CheckState newCheckValue = this . CalculateCheckState ( nmlistviewPtr2 . uNewState ) ;
if ( currentValue ! = newCheckValue )
{
// Remove the state indicies so that we don't trigger the OnItemChecked method
// when we call our base method after exiting this method
nmlistviewPtr2 . uOldState = ( nmlistviewPtr2 . uOldState & 0x0FFF ) ;
nmlistviewPtr2 . uNewState = ( nmlistviewPtr2 . uNewState & 0x0FFF ) ;
Marshal . StructureToPtr ( nmlistviewPtr2 , m . LParam , false ) ;
}
else
{
bool isSelected = ( nmlistviewPtr2 . uNewState & LVIS_SELECTED ) = = LVIS_SELECTED ;
if ( isSelected )
{
// System.Diagnostics.Debug.WriteLine(String.Format("Selected: {0}", nmlistviewPtr2.iItem));
bool isShiftDown = ( Control . ModifierKeys & Keys . Shift ) = = Keys . Shift ;
// -1 indicates that all rows are to be selected -- in fact, they already have been.
// We now have to deselect all the disabled objects.
if ( nmlistviewPtr2 . iItem = = - 1 | | isShiftDown ) {
Stopwatch sw = Stopwatch . StartNew ( ) ;
foreach ( object disabledModel in this . DisabledObjects )
{
int modelIndex = this . IndexOf ( disabledModel ) ;
if ( modelIndex > = 0 )
NativeMethods . DeselectOneItem ( this , modelIndex ) ;
}
System . Diagnostics . Debug . WriteLine ( String . Format ( "PERF - Deselecting took {0}ms / {1} ticks" , sw . ElapsedMilliseconds , sw . ElapsedTicks ) ) ;
}
else
{
// If the object just selected is disabled, explicitly de-select it
OLVListItem olvi = this . GetItem ( nmlistviewPtr2 . iItem ) ;
if ( olvi ! = null & & ! olvi . Enabled )
NativeMethods . DeselectOneItem ( this , nmlistviewPtr2 . iItem ) ;
}
}
}
}
break ;
case LVN_ITEMCHANGING :
//System.Diagnostics.Debug.WriteLine("LVN_ITEMCHANGING");
NativeMethods . NMLISTVIEW nmlistviewPtr = ( NativeMethods . NMLISTVIEW ) m . GetLParam ( typeof ( NativeMethods . NMLISTVIEW ) ) ;
if ( ( nmlistviewPtr . uChanged & LVIF_STATE ) ! = 0 ) {
CheckState currentValue = this . CalculateCheckState ( nmlistviewPtr . uOldState ) ;
CheckState newCheckValue = this . CalculateCheckState ( nmlistviewPtr . uNewState ) ;
if ( currentValue ! = newCheckValue ) {
// Prevent the base method from seeing the state change,
// since we handled it elsewhere
nmlistviewPtr . uChanged & = ~ LVIF_STATE ;
Marshal . StructureToPtr ( nmlistviewPtr , m . LParam , false ) ;
}
}
break ;
case LVN_HOTTRACK :
break ;
case LVN_GETDISPINFO :
break ;
case LVN_GROUPINFO :
//System.Diagnostics.Debug.WriteLine("reflect notify: GROUP INFO");
isMsgHandled = this . HandleGroupInfo ( ref m ) ;
break ;
//default:
//System.Diagnostics.Debug.WriteLine(String.Format("reflect notify: {0}", nmhdr.code));
//break;
}
return isMsgHandled ;
}
private bool skipNextHitTest ;
private CheckState CalculateCheckState ( int state ) {
switch ( ( state & 0xf000 ) > > 12 ) {
case 1 :
return CheckState . Unchecked ;
case 2 :
return CheckState . Checked ;
case 3 :
return CheckState . Indeterminate ;
default :
return CheckState . Checked ;
}
}
/// <summary>
/// In the notification messages, we handle attempts to change the width of our columns
/// </summary>
/// <param name="m">The m to be processed</param>
/// <returns>bool to indicate if the msg has been handled</returns>
protected bool HandleNotify ( ref Message m ) {
bool isMsgHandled = false ;
const int NM_CUSTOMDRAW = - 12 ;
const int HDN_FIRST = ( 0 - 300 ) ;
const int HDN_ITEMCHANGINGA = ( HDN_FIRST - 0 ) ;
const int HDN_ITEMCHANGINGW = ( HDN_FIRST - 20 ) ;
const int HDN_ITEMCLICKA = ( HDN_FIRST - 2 ) ;
const int HDN_ITEMCLICKW = ( HDN_FIRST - 22 ) ;
const int HDN_DIVIDERDBLCLICKA = ( HDN_FIRST - 5 ) ;
const int HDN_DIVIDERDBLCLICKW = ( HDN_FIRST - 25 ) ;
const int HDN_BEGINTRACKA = ( HDN_FIRST - 6 ) ;
const int HDN_BEGINTRACKW = ( HDN_FIRST - 26 ) ;
const int HDN_ENDTRACKA = ( HDN_FIRST - 7 ) ;
const int HDN_ENDTRACKW = ( HDN_FIRST - 27 ) ;
const int HDN_TRACKA = ( HDN_FIRST - 8 ) ;
const int HDN_TRACKW = ( HDN_FIRST - 28 ) ;
// Handle the notification, remembering to handle both ANSI and Unicode versions
NativeMethods . NMHEADER nmheader = ( NativeMethods . NMHEADER ) m . GetLParam ( typeof ( NativeMethods . NMHEADER ) ) ;
//System.Diagnostics.Debug.WriteLine(String.Format("not: {0}", nmhdr->code));
//if (nmhdr.code < HDN_FIRST)
// System.Diagnostics.Debug.WriteLine(nmhdr.code);
// In KB Article #183258, MS states that when a header control has the HDS_FULLDRAG style, it will receive
// ITEMCHANGING events rather than TRACK events. Under XP SP2 (at least) this is not always true, which may be
// why MS has withdrawn that particular KB article. It is true that the header is always given the HDS_FULLDRAG
// style. But even while window style set, the control doesn't always received ITEMCHANGING events.
// The controlling setting seems to be the Explorer option "Show Window Contents While Dragging"!
// In the category of "truly bizarre side effects", if the this option is turned on, we will receive
// ITEMCHANGING events instead of TRACK events. But if it is turned off, we receive lots of TRACK events and
// only one ITEMCHANGING event at the very end of the process.
// If we receive HDN_TRACK messages, it's harder to control the resizing process. If we return a result of 1, we
// cancel the whole drag operation, not just that particular track event, which is clearly not what we want.
// If we are willing to compile with unsafe code enabled, we can modify the size of the column in place, using the
// commented out code below. But without unsafe code, the best we can do is allow the user to drag the column to
// any width, and then spring it back to within bounds once they release the mouse button. UI-wise it's very ugly.
switch ( nmheader . nhdr . code ) {
case NM_CUSTOMDRAW :
if ( ! this . OwnerDrawnHeader )
isMsgHandled = this . HeaderControl . HandleHeaderCustomDraw ( ref m ) ;
break ;
case HDN_ITEMCLICKA :
case HDN_ITEMCLICKW :
if ( ! this . PossibleFinishCellEditing ( ) )
{
m . Result = ( IntPtr ) 1 ; // prevent the change from happening
isMsgHandled = true ;
}
break ;
case HDN_DIVIDERDBLCLICKA :
case HDN_DIVIDERDBLCLICKW :
case HDN_BEGINTRACKA :
case HDN_BEGINTRACKW :
if ( ! this . PossibleFinishCellEditing ( ) ) {
m . Result = ( IntPtr ) 1 ; // prevent the change from happening
isMsgHandled = true ;
break ;
}
if ( nmheader . iItem > = 0 & & nmheader . iItem < this . Columns . Count ) {
OLVColumn column = this . GetColumn ( nmheader . iItem ) ;
// Space filling columns can't be dragged or double-click resized
if ( column . FillsFreeSpace ) {
m . Result = ( IntPtr ) 1 ; // prevent the change from happening
isMsgHandled = true ;
}
}
break ;
case HDN_ENDTRACKA :
case HDN_ENDTRACKW :
//if (this.ShowGroups)
// this.ResizeLastGroup();
break ;
case HDN_TRACKA :
case HDN_TRACKW :
if ( nmheader . iItem > = 0 & & nmheader . iItem < this . Columns . Count ) {
NativeMethods . HDITEM hditem = ( NativeMethods . HDITEM ) Marshal . PtrToStructure ( nmheader . pHDITEM , typeof ( NativeMethods . HDITEM ) ) ;
OLVColumn column = this . GetColumn ( nmheader . iItem ) ;
if ( hditem . cxy < column . MinimumWidth )
hditem . cxy = column . MinimumWidth ;
else if ( column . MaximumWidth ! = - 1 & & hditem . cxy > column . MaximumWidth )
hditem . cxy = column . MaximumWidth ;
Marshal . StructureToPtr ( hditem , nmheader . pHDITEM , false ) ;
}
break ;
case HDN_ITEMCHANGINGA :
case HDN_ITEMCHANGINGW :
nmheader = ( NativeMethods . NMHEADER ) m . GetLParam ( typeof ( NativeMethods . NMHEADER ) ) ;
if ( nmheader . iItem > = 0 & & nmheader . iItem < this . Columns . Count ) {
NativeMethods . HDITEM hditem = ( NativeMethods . HDITEM ) Marshal . PtrToStructure ( nmheader . pHDITEM , typeof ( NativeMethods . HDITEM ) ) ;
OLVColumn column = this . GetColumn ( nmheader . iItem ) ;
// Check the mask to see if the width field is valid, and if it is, make sure it's within range
if ( ( hditem . mask & 1 ) = = 1 ) {
if ( hditem . cxy < column . MinimumWidth | |
( column . MaximumWidth ! = - 1 & & hditem . cxy > column . MaximumWidth ) ) {
m . Result = ( IntPtr ) 1 ; // prevent the change from happening
isMsgHandled = true ;
}
}
}
break ;
case ToolTipControl . TTN_SHOW :
//System.Diagnostics.Debug.WriteLine("olv TTN_SHOW");
if ( this . CellToolTip . Handle = = nmheader . nhdr . hwndFrom )
isMsgHandled = this . CellToolTip . HandleShow ( ref m ) ;
break ;
case ToolTipControl . TTN_POP :
//System.Diagnostics.Debug.WriteLine("olv TTN_POP");
if ( this . CellToolTip . Handle = = nmheader . nhdr . hwndFrom )
isMsgHandled = this . CellToolTip . HandlePop ( ref m ) ;
break ;
case ToolTipControl . TTN_GETDISPINFO :
//System.Diagnostics.Debug.WriteLine("olv TTN_GETDISPINFO");
if ( this . CellToolTip . Handle = = nmheader . nhdr . hwndFrom )
isMsgHandled = this . CellToolTip . HandleGetDispInfo ( ref m ) ;
break ;
// default:
// System.Diagnostics.Debug.WriteLine(String.Format("notify: {0}", nmheader.nhdr.code));
// break;
}
return isMsgHandled ;
}
/// <summary>
/// Create a ToolTipControl to manage the tooltip control used by the listview control
/// </summary>
protected virtual void CreateCellToolTip ( ) {
this . cellToolTip = new ToolTipControl ( ) ;
this . cellToolTip . AssignHandle ( NativeMethods . GetTooltipControl ( this ) ) ;
this . cellToolTip . Showing + = new EventHandler < ToolTipShowingEventArgs > ( HandleCellToolTipShowing ) ;
this . cellToolTip . SetMaxWidth ( ) ;
NativeMethods . MakeTopMost ( this . cellToolTip ) ;
}
/// <summary>
/// Update the handle used by our cell tooltip to be the tooltip used by
/// the underlying Windows listview control.
/// </summary>
protected virtual void UpdateCellToolTipHandle ( ) {
if ( this . cellToolTip ! = null & & this . cellToolTip . Handle = = IntPtr . Zero )
this . cellToolTip . AssignHandle ( NativeMethods . GetTooltipControl ( this ) ) ;
}
/// <summary>
/// Handle the WM_PAINT event
/// </summary>
/// <param name="m"></param>
/// <returns>Return true if the msg has been handled and nothing further should be done</returns>
protected virtual bool HandlePaint ( ref Message m ) {
//System.Diagnostics.Debug.WriteLine("> WMPAINT");
// We only want to custom draw the control within WmPaint message and only
// once per paint event. We use these bools to insure this.
this . isInWmPaintEvent = true ;
this . shouldDoCustomDrawing = true ;
this . prePaintLevel = 0 ;
this . ShowOverlays ( ) ;
this . HandlePrePaint ( ) ;
base . WndProc ( ref m ) ;
this . HandlePostPaint ( ) ;
this . isInWmPaintEvent = false ;
//System.Diagnostics.Debug.WriteLine("< WMPAINT");
return true ;
}
private int prePaintLevel ;
/// <summary>
/// Perform any steps needed before painting the control
/// </summary>
protected virtual void HandlePrePaint ( ) {
// When we get a WM_PAINT msg, remember the rectangle that is being updated.
// We can't get this information later, since the BeginPaint call wipes it out.
// this.lastUpdateRectangle = NativeMethods.GetUpdateRect(this); // we no longer need this, but keep the code so we can see it later
//// When the list is empty, we want to handle the drawing of the control by ourselves.
//// Unfortunately, there is no easy way to tell our superclass that we want to do this.
//// So we resort to guile and deception. We validate the list area of the control, which
//// effectively tells our superclass that this area does not need to be painted.
//// Our superclass will then not paint the control, leaving us free to do so ourselves.
//// Without doing this trickery, the superclass will draw the list as empty,
//// and then moments later, we will draw the empty list msg, giving a nasty flicker
//if (this.GetItemCount() == 0 && this.HasEmptyListMsg)
// NativeMethods.ValidateRect(this, this.ClientRectangle);
}
/// <summary>
/// Perform any steps needed after painting the control
/// </summary>
protected virtual void HandlePostPaint ( ) {
// This message is no longer necessary, but we keep it for compatibility
}
/// <summary>
/// Handle the window position changing.
/// </summary>
/// <param name="m">The m to be processed</param>
/// <returns>bool to indicate if the msg has been handled</returns>
protected virtual bool HandleWindowPosChanging ( ref Message m ) {
const int SWP_NOSIZE = 1 ;
NativeMethods . WINDOWPOS pos = ( NativeMethods . WINDOWPOS ) m . GetLParam ( typeof ( NativeMethods . WINDOWPOS ) ) ;
if ( ( pos . flags & SWP_NOSIZE ) = = 0 ) {
if ( pos . cx < this . Bounds . Width ) // only when shrinking
// pos.cx is the window width, not the client area width, so we have to subtract the border widths
this . ResizeFreeSpaceFillingColumns ( pos . cx - ( this . Bounds . Width - this . ClientSize . Width ) ) ;
}
return false ;
}
#endregion
#region Column header clicking , column hiding and resizing
/// <summary>
/// The user has right clicked on the column headers. Do whatever is required
/// </summary>
/// <returns>Return true if this event has been handle</returns>
protected virtual bool HandleHeaderRightClick ( int columnIndex ) {
ColumnClickEventArgs eventArgs = new ColumnClickEventArgs ( columnIndex ) ;
this . OnColumnRightClick ( eventArgs ) ;
// TODO: Allow users to say they have handled this event
return this . ShowHeaderRightClickMenu ( columnIndex , Cursor . Position ) ;
}
/// <summary>
/// Show a menu that is appropriate when the given column header is clicked.
/// </summary>
/// <param name="columnIndex">The index of the header that was clicked. This
/// can be -1, indicating that the header was clicked outside of a column</param>
/// <param name="pt">Where should the menu be shown</param>
/// <returns>True if a menu was displayed</returns>
protected virtual bool ShowHeaderRightClickMenu ( int columnIndex , Point pt ) {
ToolStripDropDown m = this . MakeHeaderRightClickMenu ( columnIndex ) ;
if ( m . Items . Count > 0 ) {
m . Show ( pt ) ;
return true ;
}
return false ;
}
/// <summary>
/// Create the menu that should be displayed when the user right clicks
/// on the given column header.
/// </summary>
/// <param name="columnIndex">Index of the column that was right clicked.
/// This can be negative, which indicates a click outside of any header.</param>
/// <returns>The toolstrip that should be displayed</returns>
protected virtual ToolStripDropDown MakeHeaderRightClickMenu ( int columnIndex ) {
ToolStripDropDown m = new ContextMenuStrip ( ) ;
if ( columnIndex > = 0 & & this . UseFiltering & & this . ShowFilterMenuOnRightClick )
m = this . MakeFilteringMenu ( m , columnIndex ) ;
if ( columnIndex > = 0 & & this . ShowCommandMenuOnRightClick )
m = this . MakeColumnCommandMenu ( m , columnIndex ) ;
if ( this . SelectColumnsOnRightClickBehaviour ! = ColumnSelectBehaviour . None ) {
m = this . MakeColumnSelectMenu ( m ) ;
}
return m ;
}
/// <summary>
/// The user has right clicked on the column headers. Do whatever is required
/// </summary>
/// <returns>Return true if this event has been handle</returns>
[Obsolete("Use HandleHeaderRightClick(int) instead")]
protected virtual bool HandleHeaderRightClick ( ) {
return false ;
}
/// <summary>
/// Show a popup menu at the given point which will allow the user to choose which columns
/// are visible on this listview
/// </summary>
/// <param name="pt">Where should the menu be placed</param>
[Obsolete("Use ShowHeaderRightClickMenu instead")]
protected virtual void ShowColumnSelectMenu ( Point pt ) {
ToolStripDropDown m = this . MakeColumnSelectMenu ( new ContextMenuStrip ( ) ) ;
m . Show ( pt ) ;
}
/// <summary>
/// Show a popup menu at the given point which will allow the user to choose which columns
/// are visible on this listview
/// </summary>
/// <param name="columnIndex"></param>
/// <param name="pt">Where should the menu be placed</param>
[Obsolete("Use ShowHeaderRightClickMenu instead")]
protected virtual void ShowColumnCommandMenu ( int columnIndex , Point pt ) {
ToolStripDropDown m = this . MakeColumnCommandMenu ( new ContextMenuStrip ( ) , columnIndex ) ;
if ( this . SelectColumnsOnRightClick ) {
if ( m . Items . Count > 0 )
m . Items . Add ( new ToolStripSeparator ( ) ) ;
this . MakeColumnSelectMenu ( m ) ;
}
m . Show ( pt ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
[Description("<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
[Category("<22> <> ǩ - ObjectListView"), DefaultValue("<22> <> <EFBFBD> <EFBFBD> {0}<7D> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> "), Localizable(true)]
public string MenuLabelSortAscending {
get { return this . menuLabelSortAscending ; }
set { this . menuLabelSortAscending = value ; }
}
private string menuLabelSortAscending = "<22> <> <EFBFBD> <EFBFBD> {0}<7D> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ;
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ڽ<EFBFBD> <DABD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
[Description("<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ڽ<EFBFBD> <DABD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
[Category("<22> <> ǩ - ObjectListView"), DefaultValue("<22> <> <EFBFBD> <EFBFBD> {0}<7D> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> "), Localizable(true)]
public string MenuLabelSortDescending {
get { return this . menuLabelSortDescending ; }
set { this . menuLabelSortDescending = value ; }
}
private string menuLabelSortDescending = "<22> <> <EFBFBD> <EFBFBD> {0}<7D> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ;
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ڷ<EFBFBD> <DAB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
[Description("<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ڷ<EFBFBD> <DAB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
[Category("<22> <> ǩ - ObjectListView"), DefaultValue("<22> <> <EFBFBD> <EFBFBD> {0}<7D> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> "), Localizable(true)]
public string MenuLabelGroupBy {
get { return this . menuLabelGroupBy ; }
set { this . menuLabelGroupBy = value ; }
}
private string menuLabelGroupBy = "<22> <> <EFBFBD> <EFBFBD> {0}<7D> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ;
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
[Description("<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
[Category("<22> <> ǩ - ObjectListView"), DefaultValue("<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> {0}<7D> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> "), Localizable(true)]
public string MenuLabelLockGroupingOn {
get { return this . menuLabelLockGroupingOn ; }
set { this . menuLabelLockGroupingOn = value ; }
}
private string menuLabelLockGroupingOn = "<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> {0}<7D> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ;
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ڲ<EFBFBD> <DAB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
[Description("<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ڲ<EFBFBD> <DAB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
[Category("<22> <> ǩ - ObjectListView"), DefaultValue("<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> {0}<7D> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> "), Localizable(true)]
public string MenuLabelUnlockGroupingOn {
get { return this . menuLabelUnlockGroupingOn ; }
set { this . menuLabelUnlockGroupingOn = value ; }
}
private string menuLabelUnlockGroupingOn = "<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> {0}<7D> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ;
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ڹرշ<D8B1> <D5B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
[Description("<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ڹرշ<D8B1> <D5B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
[Category("<22> <> ǩ - ObjectListView"), DefaultValue("<22> رշ<D8B1> <D5B7> <EFBFBD> "), Localizable(true)]
public string MenuLabelTurnOffGroups {
get { return this . menuLabelTurnOffGroups ; }
set { this . menuLabelTurnOffGroups = value ; }
}
private string menuLabelTurnOffGroups = "<22> رշ<D8B1> <D5B7> <EFBFBD> " ;
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ڲ<EFBFBD> <DAB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
[Description("<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ڲ<EFBFBD> <DAB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
[Category("<22> <> ǩ - ObjectListView"), DefaultValue("<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> "), Localizable(true)]
public string MenuLabelUnsort {
get { return this . menuLabelUnsort ; }
set { this . menuLabelUnsort = value ; }
}
private string menuLabelUnsort = "<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ;
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
[Description("<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
[Category("<22> <> ǩ - ObjectListView"), DefaultValue("<22> <> "), Localizable(true)]
public string MenuLabelColumns {
get { return this . menuLabelColumns ; }
set { this . menuLabelColumns = value ; }
}
private string menuLabelColumns = "<22> <> " ;
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
[Description("<22> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ı <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
[Category("<22> <> ǩ - ObjectListView"), DefaultValue("ѡ <> <D1A1> <EFBFBD> <EFBFBD> ..."), Localizable(true)]
public string MenuLabelSelectColumns {
get { return this . menuLabelSelectColumns ; }
set { this . menuLabelSelectColumns = value ; }
}
private string menuLabelSelectColumns = "ѡ <> <D1A1> <EFBFBD> <EFBFBD> ..." ;
/// <summary>
/// Gets or sets the image that will be place next to the Sort Ascending command
/// </summary>
static public Bitmap SortAscendingImage = ryControls . Properties . Resources . SortAscending ;
/// <summary>
/// Gets or sets the image that will be placed next to the Sort Descending command
/// </summary>
static public Bitmap SortDescendingImage = ryControls . Properties . Resources . SortDescending ;
/// <summary>
/// Append the column selection menu items to the given menu strip.
/// </summary>
/// <param name="strip">The menu to which the items will be added.</param>
/// <param name="columnIndex"></param>
/// <returns>Return the menu to which the items were added</returns>
public virtual ToolStripDropDown MakeColumnCommandMenu ( ToolStripDropDown strip , int columnIndex ) {
OLVColumn column = this . GetColumn ( columnIndex ) ;
if ( column = = null )
return strip ;
if ( strip . Items . Count > 0 )
strip . Items . Add ( new ToolStripSeparator ( ) ) ;
string label = String . Format ( this . MenuLabelSortAscending , column . Text ) ;
if ( column . Sortable & & ! String . IsNullOrEmpty ( label ) ) {
strip . Items . Add ( label , ObjectListView . SortAscendingImage , ( EventHandler ) delegate ( object sender , EventArgs args ) {
this . Sort ( column , SortOrder . Ascending ) ;
} ) ;
}
label = String . Format ( this . MenuLabelSortDescending , column . Text ) ;
if ( column . Sortable & & ! String . IsNullOrEmpty ( label ) ) {
strip . Items . Add ( label , ObjectListView . SortDescendingImage , ( EventHandler ) delegate ( object sender , EventArgs args ) {
this . Sort ( column , SortOrder . Descending ) ;
} ) ;
}
if ( this . CanShowGroups ) {
label = String . Format ( this . MenuLabelGroupBy , column . Text ) ;
if ( column . Groupable & & ! String . IsNullOrEmpty ( label ) ) {
strip . Items . Add ( label , null , ( EventHandler ) delegate ( object sender , EventArgs args ) {
this . ShowGroups = true ;
this . PrimarySortColumn = column ;
this . PrimarySortOrder = SortOrder . Ascending ;
this . BuildList ( ) ;
} ) ;
}
}
if ( this . ShowGroups ) {
if ( this . AlwaysGroupByColumn = = column ) {
label = String . Format ( this . MenuLabelUnlockGroupingOn , column . Text ) ;
if ( ! String . IsNullOrEmpty ( label ) ) {
strip . Items . Add ( label , null , ( EventHandler ) delegate ( object sender , EventArgs args ) {
this . AlwaysGroupByColumn = null ;
this . AlwaysGroupBySortOrder = SortOrder . None ;
this . BuildList ( ) ;
} ) ;
}
} else {
label = String . Format ( this . MenuLabelLockGroupingOn , column . Text ) ;
if ( column . Groupable & & ! String . IsNullOrEmpty ( label ) ) {
strip . Items . Add ( label , null , ( EventHandler ) delegate ( object sender , EventArgs args ) {
this . ShowGroups = true ;
this . AlwaysGroupByColumn = column ;
this . AlwaysGroupBySortOrder = SortOrder . Ascending ;
this . BuildList ( ) ;
} ) ;
}
}
label = String . Format ( this . MenuLabelTurnOffGroups , column . Text ) ;
if ( ! String . IsNullOrEmpty ( label ) ) {
strip . Items . Add ( label , null , ( EventHandler ) delegate ( object sender , EventArgs args ) {
this . ShowGroups = false ;
this . BuildList ( ) ;
} ) ;
}
} else {
label = String . Format ( this . MenuLabelUnsort , column . Text ) ;
if ( column . Sortable & & ! String . IsNullOrEmpty ( label ) & & this . PrimarySortOrder ! = SortOrder . None ) {
strip . Items . Add ( label , null , ( EventHandler ) delegate ( object sender , EventArgs args ) {
this . Unsort ( ) ;
} ) ;
}
}
return strip ;
}
/// <summary>
/// Append the column selection menu items to the given menu strip.
/// </summary>
/// <param name="strip">The menu to which the items will be added.</param>
/// <returns>Return the menu to which the items were added</returns>
public virtual ToolStripDropDown MakeColumnSelectMenu ( ToolStripDropDown strip ) {
System . Diagnostics . Debug . Assert ( this . SelectColumnsOnRightClickBehaviour ! = ColumnSelectBehaviour . None ) ;
// Append a separator if the menu isn't empty and the last item isn't already a separator
if ( strip . Items . Count > 0 & & ( ! ( strip . Items [ strip . Items . Count - 1 ] is ToolStripSeparator ) ) )
strip . Items . Add ( new ToolStripSeparator ( ) ) ;
if ( this . AllColumns . Count > 0 & & this . AllColumns [ 0 ] . LastDisplayIndex = = - 1 )
this . RememberDisplayIndicies ( ) ;
if ( this . SelectColumnsOnRightClickBehaviour = = ColumnSelectBehaviour . ModelDialog ) {
strip . Items . Add ( this . MenuLabelSelectColumns , null , delegate ( object sender , EventArgs args ) {
( new ColumnSelectionForm ( ) ) . OpenOn ( this ) ;
} ) ;
}
if ( this . SelectColumnsOnRightClickBehaviour = = ColumnSelectBehaviour . Submenu ) {
ToolStripMenuItem menu = new ToolStripMenuItem ( this . MenuLabelColumns ) ;
menu . DropDownItemClicked + = new ToolStripItemClickedEventHandler ( this . ColumnSelectMenuItemClicked ) ;
strip . Items . Add ( menu ) ;
this . AddItemsToColumnSelectMenu ( menu . DropDownItems ) ;
}
if ( this . SelectColumnsOnRightClickBehaviour = = ColumnSelectBehaviour . InlineMenu ) {
strip . ItemClicked + = new ToolStripItemClickedEventHandler ( this . ColumnSelectMenuItemClicked ) ;
strip . Closing + = new ToolStripDropDownClosingEventHandler ( this . ColumnSelectMenuClosing ) ;
this . AddItemsToColumnSelectMenu ( strip . Items ) ;
}
return strip ;
}
/// <summary>
/// Create the menu items that will allow columns to be choosen and add them to the
/// given collection
/// </summary>
/// <param name="items"></param>
protected void AddItemsToColumnSelectMenu ( ToolStripItemCollection items ) {
// Sort columns by display order
List < OLVColumn > columns = new List < OLVColumn > ( this . AllColumns ) ;
columns . Sort ( delegate ( OLVColumn x , OLVColumn y ) { return ( x . LastDisplayIndex - y . LastDisplayIndex ) ; } ) ;
// Build menu from sorted columns
foreach ( OLVColumn col in columns ) {
ToolStripMenuItem mi = new ToolStripMenuItem ( col . Text ) ;
mi . Checked = col . IsVisible ;
mi . Tag = col ;
// The 'Index' property returns -1 when the column is not visible, so if the
// column isn't visible we have to enable the item. Also the first column can't be turned off
mi . Enabled = ! col . IsVisible | | col . CanBeHidden ;
items . Add ( mi ) ;
}
}
private void ColumnSelectMenuItemClicked ( object sender , ToolStripItemClickedEventArgs e ) {
this . contextMenuStaysOpen = false ;
ToolStripMenuItem menuItemClicked = e . ClickedItem as ToolStripMenuItem ;
if ( menuItemClicked = = null )
return ;
OLVColumn col = menuItemClicked . Tag as OLVColumn ;
if ( col = = null )
return ;
menuItemClicked . Checked = ! menuItemClicked . Checked ;
col . IsVisible = menuItemClicked . Checked ;
this . contextMenuStaysOpen = this . SelectColumnsMenuStaysOpen ;
this . BeginInvoke ( new MethodInvoker ( this . RebuildColumns ) ) ;
}
private bool contextMenuStaysOpen ;
private void ColumnSelectMenuClosing ( object sender , ToolStripDropDownClosingEventArgs e ) {
e . Cancel = this . contextMenuStaysOpen & & e . CloseReason = = ToolStripDropDownCloseReason . ItemClicked ;
this . contextMenuStaysOpen = false ;
}
/// <summary>
/// Create a Filtering menu
/// </summary>
/// <param name="strip"></param>
/// <param name="columnIndex"></param>
/// <returns></returns>
public virtual ToolStripDropDown MakeFilteringMenu ( ToolStripDropDown strip , int columnIndex ) {
OLVColumn column = this . GetColumn ( columnIndex ) ;
if ( column = = null )
return strip ;
FilterMenuBuilder strategy = this . FilterMenuBuildStrategy ;
if ( strategy = = null )
return strip ;
return strategy . MakeFilterMenu ( strip , this , column ) ;
}
/// <summary>
/// Override the OnColumnReordered method to do what we want
/// </summary>
/// <param name="e"></param>
protected override void OnColumnReordered ( ColumnReorderedEventArgs e ) {
base . OnColumnReordered ( e ) ;
// The internal logic of the .NET code behind a ENDDRAG event means that,
// at this point, the DisplayIndex's of the columns are not yet as they are
// going to be. So we have to invoke a method to run later that will remember
// what the real DisplayIndex's are.
this . BeginInvoke ( new MethodInvoker ( this . RememberDisplayIndicies ) ) ;
}
private void RememberDisplayIndicies ( ) {
// Remember the display indexes so we can put them back at a later date
foreach ( OLVColumn x in this . AllColumns )
x . LastDisplayIndex = x . DisplayIndex ;
}
/// <summary>
/// When the column widths are changing, resize the space filling columns
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void HandleColumnWidthChanging ( object sender , ColumnWidthChangingEventArgs e ) {
if ( this . UpdateSpaceFillingColumnsWhenDraggingColumnDivider & & ! this . GetColumn ( e . ColumnIndex ) . FillsFreeSpace ) {
// If the width of a column is increasing, resize any space filling columns allowing the extra
// space that the new column width is going to consume
int oldWidth = this . GetColumn ( e . ColumnIndex ) . Width ;
if ( e . NewWidth > oldWidth )
this . ResizeFreeSpaceFillingColumns ( this . ClientSize . Width - ( e . NewWidth - oldWidth ) ) ;
else
this . ResizeFreeSpaceFillingColumns ( ) ;
}
}
/// <summary>
/// When the column widths change, resize the space filling columns
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void HandleColumnWidthChanged ( object sender , ColumnWidthChangedEventArgs e ) {
if ( ! this . GetColumn ( e . ColumnIndex ) . FillsFreeSpace )
this . ResizeFreeSpaceFillingColumns ( ) ;
}
/// <summary>
/// When the size of the control changes, we have to resize our space filling columns.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void HandleLayout ( object sender , LayoutEventArgs e ) {
// We have to delay executing the recalculation of the columns, since virtual lists
// get terribly confused if we resize the column widths during this event.
if ( ! this . hasResizeColumnsHandler ) {
this . hasResizeColumnsHandler = true ;
this . RunWhenIdle ( this . HandleApplicationIdleResizeColumns ) ;
}
}
private void RunWhenIdle ( EventHandler eventHandler ) {
Application . Idle + = eventHandler ;
if ( ! this . CanUseApplicationIdle ) {
SynchronizationContext . Current . Post ( delegate ( object x ) { Application . RaiseIdle ( EventArgs . Empty ) ; } , null ) ;
}
}
/// <summary>
/// Resize our space filling columns so they fill any unoccupied width in the control
/// </summary>
protected virtual void ResizeFreeSpaceFillingColumns ( ) {
this . ResizeFreeSpaceFillingColumns ( this . ClientSize . Width ) ;
}
/// <summary>
/// Resize our space filling columns so they fill any unoccupied width in the control
/// </summary>
protected virtual void ResizeFreeSpaceFillingColumns ( int freeSpace ) {
// It's too confusing to dynamically resize columns at design time.
if ( this . DesignMode )
return ;
if ( this . Frozen )
return ;
// Calculate the free space available
int totalProportion = 0 ;
List < OLVColumn > spaceFillingColumns = new List < OLVColumn > ( ) ;
for ( int i = 0 ; i < this . Columns . Count ; i + + ) {
OLVColumn col = this . GetColumn ( i ) ;
if ( col . FillsFreeSpace ) {
spaceFillingColumns . Add ( col ) ;
totalProportion + = col . FreeSpaceProportion ;
} else
freeSpace - = col . Width ;
}
freeSpace = Math . Max ( 0 , freeSpace ) ;
// Any space filling column that would hit it's Minimum or Maximum
// width must be treated as a fixed column.
foreach ( OLVColumn col in spaceFillingColumns . ToArray ( ) ) {
int newWidth = ( freeSpace * col . FreeSpaceProportion ) / totalProportion ;
if ( col . MinimumWidth ! = - 1 & & newWidth < col . MinimumWidth )
newWidth = col . MinimumWidth ;
else if ( col . MaximumWidth ! = - 1 & & newWidth > col . MaximumWidth )
newWidth = col . MaximumWidth ;
else
newWidth = 0 ;
if ( newWidth > 0 ) {
col . Width = newWidth ;
freeSpace - = newWidth ;
totalProportion - = col . FreeSpaceProportion ;
spaceFillingColumns . Remove ( col ) ;
}
}
// Distribute the free space between the columns
foreach ( OLVColumn col in spaceFillingColumns ) {
col . Width = ( freeSpace * col . FreeSpaceProportion ) / totalProportion ;
}
}
#endregion
#region Checkboxes
/// <summary>
/// Check all rows
/// </summary>
public virtual void CheckAll ( )
{
this . CheckedObjects = EnumerableToArray ( this . Objects , false ) ;
}
/// <summary>
/// Check the checkbox in the given column header
/// </summary>
/// <remarks>If the given columns header check box is linked to the cell check boxes,
/// then checkboxes in all cells will also be checked.</remarks>
/// <param name="column"></param>
public virtual void CheckHeaderCheckBox ( OLVColumn column )
{
if ( column = = null )
return ;
ChangeHeaderCheckBoxState ( column , CheckState . Checked ) ;
}
/// <summary>
/// Mark the checkbox in the given column header as having an indeterminate value
/// </summary>
/// <param name="column"></param>
public virtual void CheckIndeterminateHeaderCheckBox ( OLVColumn column )
{
if ( column = = null )
return ;
ChangeHeaderCheckBoxState ( column , CheckState . Indeterminate ) ;
}
/// <summary>
/// Mark the given object as indeterminate check state
/// </summary>
/// <param name="modelObject">The model object to be marked indeterminate</param>
public virtual void CheckIndeterminateObject ( object modelObject ) {
this . SetObjectCheckedness ( modelObject , CheckState . Indeterminate ) ;
}
/// <summary>
/// Mark the given object as checked in the list
/// </summary>
/// <param name="modelObject">The model object to be checked</param>
public virtual void CheckObject ( object modelObject ) {
this . SetObjectCheckedness ( modelObject , CheckState . Checked ) ;
}
/// <summary>
/// Mark the given objects as checked in the list
/// </summary>
/// <param name="modelObjects">The model object to be checked</param>
public virtual void CheckObjects ( IEnumerable modelObjects ) {
foreach ( object model in modelObjects )
this . CheckObject ( model ) ;
}
/// <summary>
/// Put a check into the check box at the given cell
/// </summary>
/// <param name="rowObject"></param>
/// <param name="column"></param>
public virtual void CheckSubItem ( object rowObject , OLVColumn column ) {
if ( column = = null | | rowObject = = null | | ! column . CheckBoxes )
return ;
column . PutCheckState ( rowObject , CheckState . Checked ) ;
this . RefreshObject ( rowObject ) ;
}
/// <summary>
/// Put an indeterminate check into the check box at the given cell
/// </summary>
/// <param name="rowObject"></param>
/// <param name="column"></param>
public virtual void CheckIndeterminateSubItem ( object rowObject , OLVColumn column ) {
if ( column = = null | | rowObject = = null | | ! column . CheckBoxes )
return ;
column . PutCheckState ( rowObject , CheckState . Indeterminate ) ;
this . RefreshObject ( rowObject ) ;
}
/// <summary>
/// Return true of the given object is checked
/// </summary>
/// <param name="modelObject">The model object whose checkedness is returned</param>
/// <returns>Is the given object checked?</returns>
/// <remarks>If the given object is not in the list, this method returns false.</remarks>
public virtual bool IsChecked ( object modelObject ) {
return this . GetCheckState ( modelObject ) = = CheckState . Checked ;
}
/// <summary>
/// Return true of the given object is indeterminately checked
/// </summary>
/// <param name="modelObject">The model object whose checkedness is returned</param>
/// <returns>Is the given object indeterminately checked?</returns>
/// <remarks>If the given object is not in the list, this method returns false.</remarks>
public virtual bool IsCheckedIndeterminate ( object modelObject ) {
return this . GetCheckState ( modelObject ) = = CheckState . Indeterminate ;
}
/// <summary>
/// Is there a check at the check box at the given cell
/// </summary>
/// <param name="rowObject"></param>
/// <param name="column"></param>
public virtual bool IsSubItemChecked ( object rowObject , OLVColumn column ) {
if ( column = = null | | rowObject = = null | | ! column . CheckBoxes )
return false ;
return ( column . GetCheckState ( rowObject ) = = CheckState . Checked ) ;
}
/// <summary>
/// Get the checkedness of an object from the model. Returning null means the
/// model does not know and the value from the control will be used.
/// </summary>
/// <param name="modelObject"></param>
/// <returns></returns>
protected virtual CheckState ? GetCheckState ( Object modelObject ) {
if ( this . CheckStateGetter ! = null )
return this . CheckStateGetter ( modelObject ) ;
return this . PersistentCheckBoxes ? this . GetPersistentCheckState ( modelObject ) : ( CheckState ? ) null ;
}
/// <summary>
/// Record the change of checkstate for the given object in the model.
/// This does not update the UI -- only the model
/// </summary>
/// <param name="modelObject"></param>
/// <param name="state"></param>
/// <returns>The check state that was recorded and that should be used to update
/// the control.</returns>
protected virtual CheckState PutCheckState ( Object modelObject , CheckState state ) {
if ( this . CheckStatePutter ! = null )
return this . CheckStatePutter ( modelObject , state ) ;
return this . PersistentCheckBoxes ? this . SetPersistentCheckState ( modelObject , state ) : state ;
}
/// <summary>
/// Change the check state of the given object to be the given state.
/// </summary>
/// <remarks>
/// If the given model object isn't in the list, we still try to remember
/// its state, in case it is referenced in the future.</remarks>
/// <param name="modelObject"></param>
/// <param name="state"></param>
/// <returns>True if the checkedness of the model changed</returns>
protected virtual bool SetObjectCheckedness ( object modelObject , CheckState state ) {
if ( GetCheckState ( modelObject ) = = state )
return false ;
OLVListItem olvi = this . ModelToItem ( modelObject ) ;
// If we didn't find the given, we still try to record the check state.
if ( olvi = = null ) {
this . PutCheckState ( modelObject , state ) ;
return true ;
}
// Trigger checkbox changing event
ItemCheckEventArgs ice = new ItemCheckEventArgs ( olvi . Index , state , olvi . CheckState ) ;
this . OnItemCheck ( ice ) ;
if ( ice . NewValue = = olvi . CheckState )
return false ;
olvi . CheckState = this . PutCheckState ( modelObject , state ) ;
this . RefreshItem ( olvi ) ;
// Trigger check changed event
this . OnItemChecked ( new ItemCheckedEventArgs ( olvi ) ) ;
return true ;
}
/// <summary>
/// Toggle the checkedness of the given object. A checked object becomes
/// unchecked; an unchecked or indeterminate object becomes checked.
/// If the list has tristate checkboxes, the order is:
/// unchecked -> checked -> indeterminate -> unchecked ...
/// </summary>
/// <param name="modelObject">The model object to be checked</param>
public virtual void ToggleCheckObject ( object modelObject ) {
OLVListItem olvi = this . ModelToItem ( modelObject ) ;
if ( olvi = = null )
return ;
CheckState newState = CheckState . Checked ;
if ( olvi . CheckState = = CheckState . Checked ) {
newState = this . TriStateCheckBoxes ? CheckState . Indeterminate : CheckState . Unchecked ;
} else {
if ( olvi . CheckState = = CheckState . Indeterminate & & this . TriStateCheckBoxes )
newState = CheckState . Unchecked ;
}
this . SetObjectCheckedness ( modelObject , newState ) ;
}
/// <summary>
/// Toggle the checkbox in the header of the given column
/// </summary>
/// <remarks>Obviously, this is only useful if the column actually has a header checkbox.</remarks>
/// <param name="column"></param>
public virtual void ToggleHeaderCheckBox ( OLVColumn column ) {
if ( column = = null )
return ;
CheckState newState = CalculateToggledCheckState ( column . HeaderCheckState , column . HeaderTriStateCheckBox , column . HeaderCheckBoxDisabled ) ;
ChangeHeaderCheckBoxState ( column , newState ) ;
}
private void ChangeHeaderCheckBoxState ( OLVColumn column , CheckState newState ) {
// Tell the world the checkbox was clicked
HeaderCheckBoxChangingEventArgs args = new HeaderCheckBoxChangingEventArgs ( ) ;
args . Column = column ;
args . NewCheckState = newState ;
this . OnHeaderCheckBoxChanging ( args ) ;
if ( args . Cancel | | column . HeaderCheckState = = args . NewCheckState )
return ;
Stopwatch sw = Stopwatch . StartNew ( ) ;
column . HeaderCheckState = args . NewCheckState ;
this . HeaderControl . Invalidate ( column ) ;
if ( column . HeaderCheckBoxUpdatesRowCheckBoxes ) {
if ( column . Index = = 0 )
this . UpdateAllPrimaryCheckBoxes ( column ) ;
else
this . UpdateAllSubItemCheckBoxes ( column ) ;
}
Debug . WriteLine ( String . Format ( "PERF - Changing row checkboxes on {2} objects took {0}ms / {1} ticks" , sw . ElapsedMilliseconds , sw . ElapsedTicks , this . GetItemCount ( ) ) ) ;
}
private void UpdateAllPrimaryCheckBoxes ( OLVColumn column ) {
if ( ! this . CheckBoxes | | column . HeaderCheckState = = CheckState . Indeterminate )
return ;
if ( column . HeaderCheckState = = CheckState . Checked )
CheckAll ( ) ;
else
UncheckAll ( ) ;
}
private void UpdateAllSubItemCheckBoxes ( OLVColumn column ) {
if ( ! column . CheckBoxes | | column . HeaderCheckState = = CheckState . Indeterminate )
return ;
foreach ( object model in this . Objects )
column . PutCheckState ( model , column . HeaderCheckState ) ;
this . BuildList ( true ) ;
}
/// <summary>
/// Toggle the check at the check box of the given cell
/// </summary>
/// <param name="rowObject"></param>
/// <param name="column"></param>
public virtual void ToggleSubItemCheckBox ( object rowObject , OLVColumn column ) {
CheckState currentState = column . GetCheckState ( rowObject ) ;
CheckState newState = CalculateToggledCheckState ( currentState , column . TriStateCheckBoxes , false ) ;
SubItemCheckingEventArgs args = new SubItemCheckingEventArgs ( column , this . ModelToItem ( rowObject ) , column . Index , currentState , newState ) ;
this . OnSubItemChecking ( args ) ;
if ( args . Canceled )
return ;
switch ( args . NewValue ) {
case CheckState . Checked :
this . CheckSubItem ( rowObject , column ) ;
break ;
case CheckState . Indeterminate :
this . CheckIndeterminateSubItem ( rowObject , column ) ;
break ;
case CheckState . Unchecked :
this . UncheckSubItem ( rowObject , column ) ;
break ;
}
}
/// <summary>
/// Uncheck all rows
/// </summary>
public virtual void UncheckAll ( )
{
this . CheckedObjects = null ;
}
/// <summary>
/// Mark the given object as unchecked in the list
/// </summary>
/// <param name="modelObject">The model object to be unchecked</param>
public virtual void UncheckObject ( object modelObject ) {
this . SetObjectCheckedness ( modelObject , CheckState . Unchecked ) ;
}
/// <summary>
/// Mark the given objects as unchecked in the list
/// </summary>
/// <param name="modelObjects">The model object to be checked</param>
public virtual void UncheckObjects ( IEnumerable modelObjects ) {
foreach ( object model in modelObjects )
this . UncheckObject ( model ) ;
}
/// <summary>
/// Uncheck the checkbox in the given column header
/// </summary>
/// <param name="column"></param>
public virtual void UncheckHeaderCheckBox ( OLVColumn column )
{
if ( column = = null )
return ;
ChangeHeaderCheckBoxState ( column , CheckState . Unchecked ) ;
}
/// <summary>
/// Uncheck the check at the given cell
/// </summary>
/// <param name="rowObject"></param>
/// <param name="column"></param>
public virtual void UncheckSubItem ( object rowObject , OLVColumn column )
{
if ( column = = null | | rowObject = = null | | ! column . CheckBoxes )
return ;
column . PutCheckState ( rowObject , CheckState . Unchecked ) ;
this . RefreshObject ( rowObject ) ;
}
#endregion
#region OLV accessing
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> ظ<EFBFBD> <D8B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="index">Index of the column to be returned</param>
/// <returns>An OLVColumn</returns>
public virtual OLVColumn GetColumn ( int index ) {
return ( OLVColumn ) this . Columns [ index ] ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> ظ<EFBFBD> <D8B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <E2B4A6> <EFBFBD> <EFBFBD> ,<2C> <> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> ı <EFBFBD> <C4B1> <EFBFBD> ,<2C> <> Ĭ<EFBFBD> <C4AC> ֻ<EFBFBD> <D6BB> <EFBFBD> ص<EFBFBD> һ <EFBFBD> <D2BB>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
/// <param name="name">Ҫ<> <D2AA> <EFBFBD> ص<EFBFBD> <D8B5> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> </param>
2021-01-12 08:32:13 +00:00
/// <returns>An OLVColumn</returns>
public virtual OLVColumn GetColumn ( string name ) {
foreach ( ColumnHeader column in this . Columns ) {
if ( column . Text = = name )
return ( OLVColumn ) column ;
}
return null ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> ظ<EFBFBD> <D8B8> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> ɼ<EFBFBD> <C9BC> <EFBFBD> <EFBFBD> е ļ<D0B5> <C4BC> ϡ<EFBFBD> ֻ<EFBFBD> <D6BB> Tile<6C> <65> Details<6C> <73> <EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> 0<EFBFBD> С <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
/// <param name="view"><3E> <> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> ĸ<EFBFBD> <C4B8> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> У <EFBFBD> </param>
2021-01-12 08:32:13 +00:00
/// <returns>A list of columns</returns>
public virtual List < OLVColumn > GetFilteredColumns ( View view ) {
// For both detail and tile view, the first column must be included. Normally, we would
// use the ColumnHeader.Index property, but if the header is not currently part of a ListView
// that property returns -1. So, we track the index of
// the column header, and always include the first header.
int index = 0 ;
return this . AllColumns . FindAll ( delegate ( OLVColumn x ) {
return ( index + + = = 0 ) | | x . IsVisible ;
} ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> е <EFBFBD> <D0B5> <EFBFBD> Ŀ<EFBFBD> <C4BF>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
/// <returns><3E> б <EFBFBD> <D0B1> е <EFBFBD> <D0B5> <EFBFBD> Ŀ<EFBFBD> <C4BF> </returns>
/// <remarks><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> װ<EFBFBD> <D7B0> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> ⽫<EFBFBD> <E2BDAB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1> ƥ<EFBFBD> <C6A5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> </remarks>
2021-01-12 08:32:13 +00:00
public virtual int GetItemCount ( ) {
return this . Items . Count ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> ظ<EFBFBD> <D8B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="index">Index of the item to be returned</param>
/// <returns>An OLVListItem</returns>
public virtual OLVListItem GetItem ( int index ) {
if ( index < 0 | | index > = this . GetItemCount ( ) )
return null ;
return ( OLVListItem ) this . Items [ index ] ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> ظ<EFBFBD> <D8B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="index">Index of the model object to be returned</param>
/// <returns>A model object</returns>
public virtual object GetModelObject ( int index ) {
OLVListItem item = this . GetItem ( index ) ;
return item = = null ? null : item . RowObject ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> ҳ<EFBFBD> <D2B3> ڸ<EFBFBD> <DAB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> µ<EFBFBD> <C2B5> к<EFBFBD> <D0BA> <EFBFBD> </summary>
/// <param name="x">X <20> <> <EFBFBD> <EFBFBD> </param>
/// <param name="y">Y <20> <> <EFBFBD> <EFBFBD> </param>
/// <param name="hitColumn"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> µ<EFBFBD> <C2B5> <EFBFBD> <EFBFBD> <EFBFBD> </param>
/// <returns><3E> ڸ<EFBFBD> <DAB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> µ<EFBFBD> <C2B5> <EFBFBD> <EFBFBD> <EFBFBD> <EEA1A3> <EFBFBD> <EFBFBD> Ϊnull<6C> <6C> </returns>
2021-01-12 08:32:13 +00:00
public virtual OLVListItem GetItemAt ( int x , int y , out OLVColumn hitColumn ) {
hitColumn = null ;
ListViewHitTestInfo info = this . HitTest ( x , y ) ;
if ( info . Item = = null )
return null ;
if ( info . SubItem ! = null ) {
int subItemIndex = info . Item . SubItems . IndexOf ( info . SubItem ) ;
hitColumn = this . GetColumn ( subItemIndex ) ;
}
return ( OLVListItem ) info . Item ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> ظ<EFBFBD> <D8B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> /<2F> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="index">Index of the item to be returned</param>
/// <param name="columnIndex">Index of the subitem to be returned</param>
/// <returns>An OLVListSubItem</returns>
public virtual OLVListSubItem GetSubItem ( int index , int columnIndex ) {
OLVListItem olvi = this . GetItem ( index ) ;
return olvi = = null ? null : olvi . GetSubItem ( columnIndex ) ;
}
#endregion
#region Object manipulation
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> ʹ <EFBFBD> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ<EFBFBD> ڶ<EFBFBD> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="lvg">The group to be revealed</param>
/// <remarks><para>
2021-01-23 15:35:30 +00:00
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɼ<EFBFBD> <C9BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ܣ<EFBFBD> <DCA3> б <EFBFBD> <D0B1> Խ<EFBFBD> <D4BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Խ<EFBFBD> <D4BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </para>
2021-01-23 15:35:30 +00:00
/// <para><3E> <> ֻ<EFBFBD> <D6BB> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> Ч(<28> <> Ȼ)<29> <> </para>
/// <para><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> ϲ <EFBFBD> <CFB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ã<EFBFBD> <C3A3> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ʹ <EFBFBD> <CAB9> ListViewGroups<70> <73> <EFBFBD> з<EFBFBD> <D0B7> 顣ʹ <E9A1A3> <CAB9> <see cref="VirtualObjectListView.EnsureNthGroupVisible"/> <20> <> <EFBFBD> <EFBFBD> .</para>
2021-01-12 08:32:13 +00:00
/// </remarks>
public virtual void EnsureGroupVisible ( ListViewGroup lvg ) {
if ( ! this . ShowGroups | | lvg = = null )
return ;
int groupIndex = this . Groups . IndexOf ( lvg ) ;
if ( groupIndex < = 0 ) {
// There is no easy way to scroll back to the beginning of the list
int delta = 0 - NativeMethods . GetScrollPosition ( this , false ) ;
NativeMethods . Scroll ( this , 0 , delta ) ;
} else {
// Find the display rectangle of the last item in the previous group
ListViewGroup previousGroup = this . Groups [ groupIndex - 1 ] ;
ListViewItem lastItemInGroup = previousGroup . Items [ previousGroup . Items . Count - 1 ] ;
Rectangle r = this . GetItemRect ( lastItemInGroup . Index ) ;
// Scroll so that the last item of the previous group is just out of sight,
// which will make the desired group header visible.
int delta = r . Y + r . Height / 2 ;
NativeMethods . Scroll ( this , 0 , delta ) ;
}
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// ʹ <> <CAB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> ɼ<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="modelObject">The model object to be revealed</param>
public virtual void EnsureModelVisible ( Object modelObject ) {
int index = this . IndexOf ( modelObject ) ;
if ( index > = 0 )
this . EnsureVisible ( index ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> е <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> null
2021-01-12 08:32:13 +00:00
/// </summary>
/// <returns>Model object or null</returns>
2021-01-23 15:35:30 +00:00
[Obsolete("ʹ <> <CAB9> SelectedObject <20> <> <EFBFBD> Դ<EFBFBD> <D4B4> 汾<EFBFBD> <E6B1BE> <EFBFBD> <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
public virtual object GetSelectedObject ( ) {
return this . SelectedObject ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
///<2F> <> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> е <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> ؿռ <D8BF> <D5BC> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <returns>ArrayList</returns>
2021-01-23 15:35:30 +00:00
[Obsolete("ʹ <> <CAB9> SelectedObjects <20> <> <EFBFBD> Դ<EFBFBD> <D4B4> 汾<EFBFBD> <E6B1BE> <EFBFBD> <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
public virtual ArrayList GetSelectedObjects ( ) {
return ObjectListView . EnumerableToArray ( this . SelectedObjects , false ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> е <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> δѡ <CEB4> <D1A1> <EFBFBD> л<EFBFBD> ѡ <EFBFBD> ж<EFBFBD> <D0B6> У <EFBFBD> <D0A3> <EFBFBD> NULL
2021-01-12 08:32:13 +00:00
/// </summary>
/// <returns>Model object or null</returns>
2021-01-23 15:35:30 +00:00
/// <remarks>ʹ <> <CAB9> CheckedObject <20> <> <EFBFBD> Դ<EFBFBD> <D4B4> 汾<EFBFBD> <E6B1BE> <EFBFBD> <EFBFBD> </remarks>
[Obsolete("ʹ <> <CAB9> CheckedObject <20> <> <EFBFBD> Դ<EFBFBD> <D4B4> 汾<EFBFBD> <E6B1BE> <EFBFBD> <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
public virtual object GetCheckedObject ( ) {
return this . CheckedObject ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> ȡѡ <C8A1> е <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> ļ<EFBFBD> <C4BC> ϡ<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
/// <remarks>ʹ <> <CAB9> CheckedObjects <20> <> <EFBFBD> Դ<EFBFBD> <D4B4> 汾<EFBFBD> <E6B1BE> <EFBFBD> <EFBFBD> </remarks>
[Obsolete("ʹ <> <CAB9> CheckedObjects <20> <> <EFBFBD> Դ<EFBFBD> <D4B4> 汾<EFBFBD> <E6B1BE> <EFBFBD> <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
public virtual ArrayList GetCheckedObjects ( ) {
return ObjectListView . EnumerableToArray ( this . CheckedObjects , false ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> в<EFBFBD> <D0B2> Ҹ<EFBFBD> <D2B8> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <F3B2A2B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="modelObject">The model object to be found</param>
/// <returns>The index of the object. -1 means the object was not present</returns>
public virtual int IndexOf ( Object modelObject ) {
for ( int i = 0 ; i < this . GetItemCount ( ) ; i + + ) {
if ( this . GetModelObject ( i ) . Equals ( modelObject ) )
return i ;
}
return - 1 ;
}
/// <summary>
/// Rebuild the given ListViewItem with the data from its associated model.
/// </summary>
/// <remarks>This method does not resort or regroup the view. It simply updates
/// the displayed data of the given item</remarks>
public virtual void RefreshItem ( OLVListItem olvi ) {
olvi . UseItemStyleForSubItems = true ;
olvi . SubItems . Clear ( ) ;
this . FillInValues ( olvi , olvi . RowObject ) ;
this . PostProcessOneRow ( olvi . Index , this . GetDisplayOrderOfItemIndex ( olvi . Index ) , olvi ) ;
}
/// <summary>
/// Rebuild the data on the row that is showing the given object.
/// </summary>
/// <remarks>
/// <para>
/// This method does not resort or regroup the view.
/// </para>
/// <para>
/// The given object is *not* used as the source of data for the rebuild.
/// It is only used to locate the matching model in the <see cref="Objects"/> collection,
/// then that matching model is used as the data source. This distinction is
/// only important in model classes that have overridden the Equals() method.
/// </para>
/// <para>
/// If you want the given model object to replace the pre-existing model,
/// use <see cref="UpdateObject"/>.
/// </para>
/// </remarks>
public virtual void RefreshObject ( object modelObject ) {
this . RefreshObjects ( new object [ ] { modelObject } ) ;
}
/// <summary>
/// Update the rows that are showing the given objects
/// </summary>
/// <remarks>
/// <para>This method does not resort or regroup the view.</para>
/// <para>This method can safely be called from background threads.</para>
/// </remarks>
public virtual void RefreshObjects ( IList modelObjects ) {
if ( this . InvokeRequired ) {
this . Invoke ( ( MethodInvoker ) delegate { this . RefreshObjects ( modelObjects ) ; } ) ;
return ;
}
foreach ( object modelObject in modelObjects ) {
OLVListItem olvi = this . ModelToItem ( modelObject ) ;
if ( olvi ! = null ) {
this . ReplaceModel ( olvi , modelObject ) ;
this . RefreshItem ( olvi ) ;
}
}
}
private void ReplaceModel ( OLVListItem olvi , object newModel ) {
if ( ReferenceEquals ( olvi . RowObject , newModel ) )
return ;
this . TakeOwnershipOfObjects ( ) ;
ArrayList array = ObjectListView . EnumerableToArray ( this . Objects , false ) ;
int i = array . IndexOf ( olvi . RowObject ) ;
if ( i > = 0 )
array [ i ] = newModel ;
olvi . RowObject = newModel ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>This method does not resort or regroup the view.</remarks>
public virtual void RefreshSelectedObjects ( ) {
foreach ( ListViewItem lvi in this . SelectedItems )
this . RefreshItem ( ( OLVListItem ) lvi ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> κε<CEBA> ǰѡ <C7B0> <D1A1> <EFBFBD> ⣬<EFBFBD> <E2A3AC> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="modelObject">The object to be selected</param>
/// <remarks>Use the <see cref="SelectedObject"/> property to deselect all other rows</remarks>
public virtual void SelectObject ( object modelObject ) {
this . SelectObject ( modelObject , false ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> κε<CEBA> ǰѡ <C7B0> <D1A1> <EFBFBD> ⣬<EFBFBD> <E2A3AC> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="modelObject">The object to be selected</param>
2021-01-23 15:35:30 +00:00
/// <param name="setFocus"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> ҲӦ<D2B2> ñ<EFBFBD> <C3B1> ۽<EFBFBD> </param>
2021-01-12 08:32:13 +00:00
/// <remarks>Use the <see cref="SelectedObject"/> property to deselect all other rows</remarks>
public virtual void SelectObject ( object modelObject , bool setFocus ) {
OLVListItem olvi = this . ModelToItem ( modelObject ) ;
if ( olvi ! = null & & olvi . Enabled ) {
olvi . Selected = true ;
if ( setFocus )
olvi . Focused = true ;
}
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// ѡ <> <D1A1> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> ȡ<EFBFBD> <C8A1> ѡ <EFBFBD> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="modelObjects">A collection of model objects</param>
public virtual void SelectObjects ( IList modelObjects ) {
this . SelectedIndices . Clear ( ) ;
if ( modelObjects = = null )
return ;
foreach ( object modelObject in modelObjects ) {
OLVListItem olvi = this . ModelToItem ( modelObject ) ;
if ( olvi ! = null & & olvi . Enabled )
olvi . Selected = true ;
}
}
#endregion
#region Freezing / Suspending
/// <summary>
2021-01-23 15:35:30 +00:00
///<2F> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<C7B7> <F1B6B3BD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҹ<EFBFBD> <D2B8> ¡<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
/// <remarks><para>Frozen<65> <6E> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Freeze()/UnFreeze()<29> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƣ<EFBFBD>
/// <20> <> ֮ͬ<CDAC> <D6AE> <EFBFBD> <EFBFBD> <EFBFBD> ڽ<EFBFBD> Frozen<65> <6E> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ΪFalse<73> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ⶳ<EFBFBD> ؼ<EFBFBD> <D8BC> <EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD> ɵ<EFBFBD> Freeze()<29> <> <EFBFBD> á<EFBFBD> </para></remarks>
2021-01-12 08:32:13 +00:00
/// <example>objectListView1.Frozen = false; // unfreeze the control now!
/// </example>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
public virtual bool Frozen {
get { return freezeCount > 0 ; }
set {
if ( value )
Freeze ( ) ;
else if ( freezeCount > 0 ) {
freezeCount = 1 ;
Unfreeze ( ) ;
}
}
}
private int freezeCount ;
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> ʹ <EFBFBD> 䲻<EFBFBD> <E4B2BB> <EFBFBD> <EFBFBD> <EFBFBD> Ҹ<EFBFBD> <D2B8> ¡<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>Freeze()/Unfreeze() calls nest correctly</remarks>
public virtual void Freeze ( ) {
if ( freezeCount = = 0 )
DoFreeze ( ) ;
freezeCount + + ;
this . OnFreezing ( new FreezeEventArgs ( freezeCount ) ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> ⶳ<EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ˵<EFBFBD> <CBB5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> unFreeze()<29> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ¹<EFBFBD> <C2B9> <EFBFBD> listview<65> <77> <EFBFBD> <EFBFBD> <EFBFBD> ݡ<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>Freeze()/Unfreeze() calls nest correctly</remarks>
public virtual void Unfreeze ( ) {
if ( freezeCount < = 0 )
return ;
freezeCount - - ;
if ( freezeCount = = 0 )
DoUnfreeze ( ) ;
this . OnFreezing ( new FreezeEventArgs ( freezeCount ) ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> ڶ<EFBFBD> <DAB6> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼʱִ<CAB1> <D6B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʵ<EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
protected virtual void DoFreeze ( ) {
this . BeginUpdate ( ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> ⶳ<EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼʱִ<CAB1> <D6B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʵ<EFBFBD> ʹ <EFBFBD> <CAB9> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
protected virtual void DoUnfreeze ( )
{
this . EndUpdate ( ) ;
this . ResizeFreeSpaceFillingColumns ( ) ;
this . BuildList ( ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> ¼<EFBFBD> <C2BC> <EFBFBD> ǰ<EFBFBD> <C7B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> TRUE<55> <45> <EFBFBD> ڹ<EFBFBD> <DAB9> <EFBFBD> ѡ <EFBFBD> <D1A1> <EFBFBD> ¼<EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SelectedIndexChanged<65> <64> SelectionChanged<65> ¼<EFBFBD> <C2BC> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
[ Browsable ( false ) ,
DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
protected bool SelectionEventsSuspended {
get { return this . suspendSelectionEventCount > 0 ; }
}
/// <summary>
/// Suspend selection events until a matching ResumeSelectionEvents()
/// is called.
/// </summary>
/// <remarks>Calls to this method nest correctly. Every call to SuspendSelectionEvents()
/// must have a matching ResumeSelectionEvents().</remarks>
protected void SuspendSelectionEvents ( ) {
this . suspendSelectionEventCount + + ;
}
/// <summary>
/// Resume raising selection events.
/// </summary>
protected void ResumeSelectionEvents ( ) {
Debug . Assert ( this . SelectionEventsSuspended , "Mismatched called to ResumeSelectionEvents()" ) ;
this . suspendSelectionEventCount - - ;
}
/// <summary>
/// Returns a disposable that will disable selection events
/// during a using() block.
/// </summary>
/// <returns></returns>
protected IDisposable SuspendSelectionEventsDuring ( ) {
return new SuspendSelectionDisposable ( this ) ;
}
/// <summary>
/// Implementation only class that suspends and resumes selection
/// events on instance creation and disposal.
/// </summary>
private class SuspendSelectionDisposable : IDisposable {
public SuspendSelectionDisposable ( ObjectListView objectListView ) {
this . objectListView = objectListView ;
this . objectListView . SuspendSelectionEvents ( ) ;
}
public void Dispose ( ) {
this . objectListView . ResumeSelectionEvents ( ) ;
}
private readonly ObjectListView objectListView ;
}
#endregion
#region Column sorting
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> к<EFBFBD> ˳<EFBFBD> <CBB3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
new public void Sort ( ) {
this . Sort ( this . PrimarySortColumn , this . PrimarySortOrder ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> ϴ<EFBFBD> <CFB4> <EFBFBD> <EFBFBD> <EFBFBD> ˳<EFBFBD> <CBB3> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
/// <param name="columnToSortName"><3E> <> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> </param>
2021-01-12 08:32:13 +00:00
public virtual void Sort ( string columnToSortName ) {
this . Sort ( this . GetColumn ( columnToSortName ) , this . PrimarySortOrder ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
///<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> ϴ<EFBFBD> <CFB4> <EFBFBD> <EFBFBD> <EFBFBD> ˳<EFBFBD> <CBB3> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
/// <param name="columnToSortIndex"><3E> <> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> </param>
2021-01-12 08:32:13 +00:00
public virtual void Sort ( int columnToSortIndex ) {
if ( columnToSortIndex > = 0 & & columnToSortIndex < this . Columns . Count )
this . Sort ( this . GetColumn ( columnToSortIndex ) , this . PrimarySortOrder ) ;
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> ϴ<EFBFBD> <CFB4> <EFBFBD> <EFBFBD> <EFBFBD> ˳<EFBFBD> <CBB3> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
2021-01-23 15:35:30 +00:00
/// <param name="columnToSort"><3E> <> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> </param>
2021-01-12 08:32:13 +00:00
public virtual void Sort ( OLVColumn columnToSort ) {
if ( this . InvokeRequired ) {
this . Invoke ( ( MethodInvoker ) delegate { this . Sort ( columnToSort ) ; } ) ;
} else {
this . Sort ( columnToSort , this . PrimarySortOrder ) ;
}
}
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> ϴ<EFBFBD> <CFB4> <EFBFBD> <EFBFBD> <EFBFBD> ˳<EFBFBD> <CBB3> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="columnToSort">The column whose values will be used for the sorting.
/// If null, the first column will be used.</param>
/// <param name="order">The ordering to be used for sorting. If this is None,
/// this.Sorting and then SortOrder.Ascending will be used</param>
/// <remarks>If ShowGroups is true, the rows will be grouped by the given column.
/// If AlwaysGroupsByColumn is not null, the rows will be grouped by that column,
/// and the rows within each group will be sorted by the given column.</remarks>
public virtual void Sort ( OLVColumn columnToSort , SortOrder order ) {
if ( this . InvokeRequired ) {
this . Invoke ( ( MethodInvoker ) delegate { this . Sort ( columnToSort , order ) ; } ) ;
} else {
this . DoSort ( columnToSort , order ) ;
this . PostProcessRows ( ) ;
}
}
private void DoSort ( OLVColumn columnToSort , SortOrder order ) {
// Sanity checks
if ( this . GetItemCount ( ) = = 0 | | this . Columns . Count = = 0 )
return ;
// Fill in default values, if the parameters don't make sense
if ( this . ShowGroups ) {
columnToSort = columnToSort ? ? this . GetColumn ( 0 ) ;
if ( order = = SortOrder . None ) {
order = this . Sorting ;
if ( order = = SortOrder . None )
order = SortOrder . Ascending ;
}
}
// Give the world a chance to fiddle with or completely avoid the sorting process
BeforeSortingEventArgs args = this . BuildBeforeSortingEventArgs ( columnToSort , order ) ;
this . OnBeforeSorting ( args ) ;
if ( args . Canceled )
return ;
// Virtual lists don't preserve selection, so we have to do it specifically
// THINK: Do we need to preserve focus too?
IList selection = this . VirtualMode ? this . SelectedObjects : null ;
this . SuspendSelectionEvents ( ) ;
this . ClearHotItem ( ) ;
// Finally, do the work of sorting, unless an event handler has already done the sorting for us
if ( ! args . Handled ) {
// Sanity checks
if ( args . ColumnToSort ! = null & & args . SortOrder ! = SortOrder . None ) {
if ( this . ShowGroups )
this . BuildGroups ( args . ColumnToGroupBy , args . GroupByOrder , args . ColumnToSort , args . SortOrder ,
args . SecondaryColumnToSort , args . SecondarySortOrder ) ;
else if ( this . CustomSorter ! = null )
this . CustomSorter ( args . ColumnToSort , args . SortOrder ) ;
else
this . ListViewItemSorter = new ColumnComparer ( args . ColumnToSort , args . SortOrder ,
args . SecondaryColumnToSort , args . SecondarySortOrder ) ;
}
}
if ( this . ShowSortIndicators )
this . ShowSortIndicator ( args . ColumnToSort , args . SortOrder ) ;
this . PrimarySortColumn = args . ColumnToSort ;
this . PrimarySortOrder = args . SortOrder ;
if ( selection ! = null & & selection . Count > 0 )
this . SelectedObjects = selection ;
this . ResumeSelectionEvents ( ) ;
this . RefreshHotItem ( ) ;
this . OnAfterSorting ( new AfterSortingEventArgs ( args ) ) ;
}
/// <summary>
/// Put a sort indicator next to the text of the sort column
/// </summary>
public virtual void ShowSortIndicator ( ) {
if ( this . ShowSortIndicators & & this . PrimarySortOrder ! = SortOrder . None )
this . ShowSortIndicator ( this . PrimarySortColumn , this . PrimarySortOrder ) ;
}
/// <summary>
/// Put a sort indicator next to the text of the given given column
/// </summary>
/// <param name="columnToSort">The column to be marked</param>
/// <param name="sortOrder">The sort order in effect on that column</param>
protected virtual void ShowSortIndicator ( OLVColumn columnToSort , SortOrder sortOrder ) {
int imageIndex = - 1 ;
if ( ! NativeMethods . HasBuiltinSortIndicators ( ) ) {
// If we can't use builtin image, we have to make and then locate the index of the
// sort indicator we want to use. SortOrder.None doesn't show an image.
if ( this . SmallImageList = = null | | ! this . SmallImageList . Images . ContainsKey ( SORT_INDICATOR_UP_KEY ) )
MakeSortIndicatorImages ( ) ;
if ( this . SmallImageList ! = null )
{
string key = sortOrder = = SortOrder . Ascending ? SORT_INDICATOR_UP_KEY : SORT_INDICATOR_DOWN_KEY ;
imageIndex = this . SmallImageList . Images . IndexOfKey ( key ) ;
}
}
// Set the image for each column
for ( int i = 0 ; i < this . Columns . Count ; i + + ) {
if ( columnToSort ! = null & & i = = columnToSort . Index )
NativeMethods . SetColumnImage ( this , i , sortOrder , imageIndex ) ;
else
NativeMethods . SetColumnImage ( this , i , SortOrder . None , - 1 ) ;
}
}
/// <summary>
/// The name of the image used when a column is sorted ascending
/// </summary>
/// <remarks>This image is only used on pre-XP systems. System images are used for XP and later</remarks>
public const string SORT_INDICATOR_UP_KEY = "sort-indicator-up" ;
/// <summary>
/// The name of the image used when a column is sorted descending
/// </summary>
/// <remarks>This image is only used on pre-XP systems. System images are used for XP and later</remarks>
public const string SORT_INDICATOR_DOWN_KEY = "sort-indicator-down" ;
/// <summary>
/// If the sort indicator images don't already exist, this method will make and install them
/// </summary>
protected virtual void MakeSortIndicatorImages ( ) {
// Don't mess with the image list in design mode
if ( this . DesignMode )
return ;
ImageList il = this . SmallImageList ;
if ( il = = null ) {
il = new ImageList ( ) ;
il . ImageSize = new Size ( 16 , 16 ) ;
il . ColorDepth = ColorDepth . Depth32Bit ;
}
// This arrangement of points works well with (16,16) images, and OK with others
int midX = il . ImageSize . Width / 2 ;
int midY = ( il . ImageSize . Height / 2 ) - 1 ;
int deltaX = midX - 2 ;
int deltaY = deltaX / 2 ;
if ( il . Images . IndexOfKey ( SORT_INDICATOR_UP_KEY ) = = - 1 ) {
Point pt1 = new Point ( midX - deltaX , midY + deltaY ) ;
Point pt2 = new Point ( midX , midY - deltaY - 1 ) ;
Point pt3 = new Point ( midX + deltaX , midY + deltaY ) ;
il . Images . Add ( SORT_INDICATOR_UP_KEY , this . MakeTriangleBitmap ( il . ImageSize , new Point [ ] { pt1 , pt2 , pt3 } ) ) ;
}
if ( il . Images . IndexOfKey ( SORT_INDICATOR_DOWN_KEY ) = = - 1 ) {
Point pt1 = new Point ( midX - deltaX , midY - deltaY ) ;
Point pt2 = new Point ( midX , midY + deltaY ) ;
Point pt3 = new Point ( midX + deltaX , midY - deltaY ) ;
il . Images . Add ( SORT_INDICATOR_DOWN_KEY , this . MakeTriangleBitmap ( il . ImageSize , new Point [ ] { pt1 , pt2 , pt3 } ) ) ;
}
this . SmallImageList = il ;
}
private Bitmap MakeTriangleBitmap ( Size sz , Point [ ] pts ) {
Bitmap bm = new Bitmap ( sz . Width , sz . Height ) ;
Graphics g = Graphics . FromImage ( bm ) ;
g . FillPolygon ( new SolidBrush ( Color . Gray ) , pts ) ;
return bm ;
}
/// <summary>
/// Remove any sorting and revert to the given order of the model objects
/// </summary>
public virtual void Unsort ( ) {
this . ShowGroups = false ;
this . PrimarySortColumn = null ;
this . PrimarySortOrder = SortOrder . None ;
this . BuildList ( ) ;
}
#endregion
#region Utilities
private static CheckState CalculateToggledCheckState ( CheckState currentState , bool isTriState , bool isDisabled )
{
if ( isDisabled )
return currentState ;
switch ( currentState )
{
case CheckState . Checked : return isTriState ? CheckState . Indeterminate : CheckState . Unchecked ;
case CheckState . Indeterminate : return CheckState . Unchecked ;
default : return CheckState . Checked ;
}
}
/// <summary>
/// Do the actual work of creating the given list of groups
/// </summary>
/// <param name="groups"></param>
protected virtual void CreateGroups ( IEnumerable < OLVGroup > groups ) {
this . Groups . Clear ( ) ;
// The group must be added before it is given items, otherwise an exception is thrown (is this documented?)
foreach ( OLVGroup group in groups ) {
group . InsertGroupOldStyle ( this ) ;
group . SetItemsOldStyle ( ) ;
}
}
/// <summary>
/// For some reason, UseItemStyleForSubItems doesn't work for the colors
/// when owner drawing the list, so we have to specifically give each subitem
/// the desired colors
/// </summary>
/// <param name="olvi">The item whose subitems are to be corrected</param>
/// <remarks>Cells drawn via BaseRenderer don't need this, but it is needed
/// when an owner drawn cell uses DrawDefault=true</remarks>
protected virtual void CorrectSubItemColors ( ListViewItem olvi ) {
}
/// <summary>
/// Fill in the given OLVListItem with values of the given row
/// </summary>
/// <param name="lvi">the OLVListItem that is to be stuff with values</param>
/// <param name="rowObject">the model object from which values will be taken</param>
protected virtual void FillInValues ( OLVListItem lvi , object rowObject ) {
if ( this . Columns . Count = = 0 )
return ;
OLVListSubItem subItem = this . MakeSubItem ( rowObject , this . GetColumn ( 0 ) ) ;
lvi . SubItems [ 0 ] = subItem ;
lvi . ImageSelector = subItem . ImageSelector ;
// Give the item the same font/colors as the control
lvi . Font = this . Font ;
lvi . BackColor = this . BackColor ;
lvi . ForeColor = this . ForeColor ;
// Should the row be selectable?
lvi . Enabled = ! this . IsDisabled ( rowObject ) ;
// Only Details and Tile views have subitems
switch ( this . View ) {
case View . Details :
for ( int i = 1 ; i < this . Columns . Count ; i + + ) {
lvi . SubItems . Add ( this . MakeSubItem ( rowObject , this . GetColumn ( i ) ) ) ;
}
break ;
case View . Tile :
for ( int i = 1 ; i < this . Columns . Count ; i + + ) {
OLVColumn column = this . GetColumn ( i ) ;
if ( column . IsTileViewColumn )
lvi . SubItems . Add ( this . MakeSubItem ( rowObject , column ) ) ;
}
break ;
}
// Should the row be selectable?
if ( ! lvi . Enabled ) {
lvi . UseItemStyleForSubItems = false ;
ApplyRowStyle ( lvi , this . DisabledItemStyle ? ? ObjectListView . DefaultDisabledItemStyle ) ;
}
// Set the check state of the row, if we are showing check boxes
if ( this . CheckBoxes ) {
CheckState ? state = this . GetCheckState ( lvi . RowObject ) ;
if ( state . HasValue )
lvi . CheckState = state . Value ;
}
// Give the RowFormatter a chance to mess with the item
if ( this . RowFormatter ! = null ) {
this . RowFormatter ( lvi ) ;
}
}
private OLVListSubItem MakeSubItem ( object rowObject , OLVColumn column ) {
object cellValue = column . GetValue ( rowObject ) ;
OLVListSubItem subItem = new OLVListSubItem ( cellValue ,
2021-09-12 06:54:13 +00:00
column . ValueToString ( rowObject , cellValue ) ,
2021-01-12 08:32:13 +00:00
column . GetImage ( rowObject ) ) ;
if ( this . UseHyperlinks & & column . Hyperlink ) {
IsHyperlinkEventArgs args = new IsHyperlinkEventArgs ( ) ;
args . ListView = this ;
args . Model = rowObject ;
args . Column = column ;
args . Text = subItem . Text ;
args . Url = subItem . Text ;
args . IsHyperlink = ! this . IsDisabled ( rowObject ) ;
this . OnIsHyperlink ( args ) ;
subItem . Url = args . IsHyperlink ? args . Url : null ;
}
return subItem ;
}
private void ApplyHyperlinkStyle ( OLVListItem olvi ) {
for ( int i = 0 ; i < this . Columns . Count ; i + + ) {
OLVListSubItem subItem = olvi . GetSubItem ( i ) ;
if ( subItem = = null )
continue ;
OLVColumn column = this . GetColumn ( i ) ;
if ( column . Hyperlink & & ! String . IsNullOrEmpty ( subItem . Url ) )
this . ApplyCellStyle ( olvi , i , this . IsUrlVisited ( subItem . Url ) ? this . HyperlinkStyle . Visited : this . HyperlinkStyle . Normal ) ;
}
}
/// <summary>
/// Make sure the ListView has the extended style that says to display subitem images.
/// </summary>
/// <remarks>This method must be called after any .NET call that update the extended styles
/// since they seem to erase this setting.</remarks>
protected virtual void ForceSubItemImagesExStyle ( ) {
// Virtual lists can't show subitem images natively, so don't turn on this flag
if ( ! this . VirtualMode )
NativeMethods . ForceSubItemImagesExStyle ( this ) ;
}
/// <summary>
/// Convert the given image selector to an index into our image list.
/// Return -1 if that's not possible
/// </summary>
/// <param name="imageSelector"></param>
/// <returns>Index of the image in the imageList, or -1</returns>
protected virtual int GetActualImageIndex ( Object imageSelector ) {
if ( imageSelector = = null )
return - 1 ;
if ( imageSelector is Int32 )
return ( int ) imageSelector ;
String imageSelectorAsString = imageSelector as String ;
if ( imageSelectorAsString ! = null & & this . SmallImageList ! = null )
return this . SmallImageList . Images . IndexOfKey ( imageSelectorAsString ) ;
return - 1 ;
}
/// <summary>
/// Return the tooltip that should be shown when the mouse is hovered over the given column
/// </summary>
/// <param name="columnIndex">The column index whose tool tip is to be fetched</param>
/// <returns>A string or null if no tool tip is to be shown</returns>
public virtual String GetHeaderToolTip ( int columnIndex ) {
OLVColumn column = this . GetColumn ( columnIndex ) ;
if ( column = = null )
return null ;
String tooltip = column . ToolTipText ;
if ( this . HeaderToolTipGetter ! = null )
tooltip = this . HeaderToolTipGetter ( column ) ;
return tooltip ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> ص<EFBFBD> <D8B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͣ<EFBFBD> ڸ<EFBFBD> <DAB8> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ<EFBFBD> <D4AA> <EFBFBD> <EFBFBD> ʱӦ<CAB1> <D3A6> ʾ <EFBFBD> Ĺ<EFBFBD> <C4B9> <EFBFBD> <EFBFBD> <EFBFBD> ʾ
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="columnIndex">The column index whose tool tip is to be fetched</param>
/// <param name="rowIndex">The row index whose tool tip is to be fetched</param>
/// <returns>A string or null if no tool tip is to be shown</returns>
public virtual String GetCellToolTip ( int columnIndex , int rowIndex ) {
if ( this . CellToolTipGetter ! = null )
return this . CellToolTipGetter ( this . GetColumn ( columnIndex ) , this . GetModelObject ( rowIndex ) ) ;
// Show the URL in the tooltip if it's different to the text
if ( columnIndex > = 0 ) {
OLVListSubItem subItem = this . GetSubItem ( rowIndex , columnIndex ) ;
if ( subItem ! = null & & ! String . IsNullOrEmpty ( subItem . Url ) & & subItem . Url ! = subItem . Text & &
this . HotCellHitLocation = = HitTestLocation . Text )
return subItem . Url ;
}
return null ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> <EFBFBD> OLVListItem
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="modelObject">The modelObject whose item is to be found</param>
/// <returns>The OLVListItem that displays the model, or null</returns>
/// <remarks>This method has O(n) performance.</remarks>
public virtual OLVListItem ModelToItem ( object modelObject ) {
if ( modelObject = = null )
return null ;
foreach ( OLVListItem olvi in this . Items ) {
if ( olvi . RowObject ! = null & & olvi . RowObject . Equals ( modelObject ) )
return olvi ;
}
return null ;
}
/// <summary>
/// Do the work required after the items in a listview have been created
/// </summary>
protected virtual void PostProcessRows ( ) {
// If this method is called during a BeginUpdate/EndUpdate pair, changes to the
// Items collection are cached. Getting the Count flushes that cache.
#pragma warning disable 168
// ReSharper disable once UnusedVariable
int count = this . Items . Count ;
#pragma warning restore 168
int i = 0 ;
if ( this . ShowGroups ) {
foreach ( ListViewGroup group in this . Groups ) {
foreach ( OLVListItem olvi in group . Items ) {
this . PostProcessOneRow ( olvi . Index , i , olvi ) ;
i + + ;
}
}
} else {
foreach ( OLVListItem olvi in this . Items ) {
this . PostProcessOneRow ( olvi . Index , i , olvi ) ;
i + + ;
}
}
}
/// <summary>
/// Do the work required after one item in a listview have been created
/// </summary>
protected virtual void PostProcessOneRow ( int rowIndex , int displayIndex , OLVListItem olvi ) {
if ( this . UseAlternatingBackColors & & this . View = = View . Details & & olvi . Enabled ) {
olvi . UseItemStyleForSubItems = true ;
olvi . BackColor = displayIndex % 2 = = 1 ? this . AlternateRowBackColorOrDefault : this . BackColor ;
}
if ( this . ShowImagesOnSubItems & & ! this . VirtualMode )
this . SetSubItemImages ( rowIndex , olvi ) ;
bool needToTriggerFormatCellEvents = this . TriggerFormatRowEvent ( rowIndex , displayIndex , olvi ) ;
// We only need cell level events if we are in details view
if ( this . View ! = View . Details )
return ;
// If we're going to have per cell formatting, we need to copy the formatting
// of the item into each cell, before triggering the cell format events
if ( needToTriggerFormatCellEvents ) {
PropagateFormatFromRowToCells ( olvi ) ;
this . TriggerFormatCellEvents ( rowIndex , displayIndex , olvi ) ;
}
// Similarly, if any cell in the row has hyperlinks, we have to copy formatting
// from the item into each cell before applying the hyperlink style
if ( this . UseHyperlinks & & olvi . HasAnyHyperlinks ) {
PropagateFormatFromRowToCells ( olvi ) ;
this . ApplyHyperlinkStyle ( olvi ) ;
}
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <> <D7BC> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> <EFBFBD> ɫ
2021-01-12 08:32:13 +00:00
/// </summary>
/// <remarks>We cannot rely on lvi.Index in this method.
/// In a straight list, lvi.Index is the display index, and can be used to determine
/// whether the row should be colored. But when organised by groups, lvi.Index is not
/// useable because it still refers to the position in the overall list, not the display order.
///</remarks>
2021-09-12 06:54:13 +00:00
[Obsolete("<22> <> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ô˷<C3B4> <CBB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> дPostProcessOneRow()<29> Ի<EFBFBD> <D4BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƵĽ<C6B5> <C4BD> <EFBFBD> ")]
2021-01-12 08:32:13 +00:00
protected virtual void PrepareAlternateBackColors ( ) {
}
/// <summary>
/// Setup all subitem images on all rows
/// </summary>
[Obsolete("This method is not longer maintained and will be removed", false)]
protected virtual void SetAllSubItemImages ( ) {
//if (!this.ShowImagesOnSubItems || this.OwnerDraw)
// return;
//this.ForceSubItemImagesExStyle();
//for (int rowIndex = 0; rowIndex < this.GetItemCount(); rowIndex++)
// SetSubItemImages(rowIndex, this.GetItem(rowIndex));
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <DFBB> <EFBFBD> <EFBFBD> б <EFBFBD> <D0B1> ؼ<EFBFBD> <D8BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <CABE> Щͼ<D0A9> <CDBC>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="rowIndex">the index at which the item occurs</param>
/// <param name="item">the item whose subitems are to be set</param>
protected virtual void SetSubItemImages ( int rowIndex , OLVListItem item ) {
this . SetSubItemImages ( rowIndex , item , false ) ;
}
/// <summary>
/// Tell the underlying list control which images to show against the subitems
/// </summary>
/// <param name="rowIndex">the index at which the item occurs</param>
/// <param name="item">the item whose subitems are to be set</param>
/// <param name="shouldClearImages">will existing images be cleared if no new image is provided?</param>
protected virtual void SetSubItemImages ( int rowIndex , OLVListItem item , bool shouldClearImages ) {
if ( ! this . ShowImagesOnSubItems | | this . OwnerDraw )
return ;
for ( int i = 1 ; i < item . SubItems . Count ; i + + ) {
this . SetSubItemImage ( rowIndex , i , item . GetSubItem ( i ) , shouldClearImages ) ;
}
}
/// <summary>
/// Set the subitem image natively
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="subItemIndex"></param>
/// <param name="subItem"></param>
/// <param name="shouldClearImages"></param>
public virtual void SetSubItemImage ( int rowIndex , int subItemIndex , OLVListSubItem subItem , bool shouldClearImages ) {
int imageIndex = this . GetActualImageIndex ( subItem . ImageSelector ) ;
if ( shouldClearImages | | imageIndex ! = - 1 )
NativeMethods . SetSubItemImage ( this , rowIndex , subItemIndex , imageIndex ) ;
}
/// <summary>
/// Take ownership of the 'objects' collection. This separats our collection from the source.
/// </summary>
/// <remarks>
/// <para>
/// This method
/// separates the 'objects' instance variable from its source, so that any AddObject/RemoveObject
/// calls will modify our collection and not the original colleciton.
/// </para>
/// <para>
/// This method has the intentional side-effect of converting our list of objects to an ArrayList.
/// </para>
/// </remarks>
protected virtual void TakeOwnershipOfObjects ( ) {
if ( this . isOwnerOfObjects )
return ;
this . isOwnerOfObjects = true ;
this . objects = ObjectListView . EnumerableToArray ( this . objects , true ) ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> FormatRow<6F> Ϳ <EFBFBD> <CDBF> ܵ<EFBFBD> FormatCell<6C> ¼<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="displayIndex"></param>
/// <param name="olvi"></param>
protected virtual bool TriggerFormatRowEvent ( int rowIndex , int displayIndex , OLVListItem olvi ) {
FormatRowEventArgs args = new FormatRowEventArgs ( ) ;
args . ListView = this ;
args . RowIndex = rowIndex ;
args . DisplayIndex = displayIndex ;
args . Item = olvi ;
args . UseCellFormatEvents = this . UseCellFormatEvents ;
this . OnFormatRow ( args ) ;
return args . UseCellFormatEvents ;
}
/// <summary>
2021-09-12 06:54:13 +00:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<EFBFBD> <C4BF> FormatCell<6C> ¼<EFBFBD>
2021-01-12 08:32:13 +00:00
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="displayIndex"></param>
/// <param name="olvi"></param>
protected virtual void TriggerFormatCellEvents ( int rowIndex , int displayIndex , OLVListItem olvi ) {
PropagateFormatFromRowToCells ( olvi ) ;
// Fire one event per cell
FormatCellEventArgs args2 = new FormatCellEventArgs ( ) ;
args2 . ListView = this ;
args2 . RowIndex = rowIndex ;
args2 . DisplayIndex = displayIndex ;
args2 . Item = olvi ;
for ( int i = 0 ; i < this . Columns . Count ; i + + ) {
args2 . ColumnIndex = i ;
args2 . Column = this . GetColumn ( i ) ;
args2 . SubItem = olvi . GetSubItem ( i ) ;
this . OnFormatCell ( args2 ) ;
}
}
private static void PropagateFormatFromRowToCells ( OLVListItem olvi ) {
// If a cell isn't given its own colors, it *should* use the colors of the item.
// However, there is a bug in the .NET framework where the cell are given
// the colors of the ListView instead of the colors of the row.
// If we've already done this, don't do it again
if ( olvi . UseItemStyleForSubItems = = false )
return ;
// So we have to explicitly give each cell the fore and back colors and the font that it should have.
olvi . UseItemStyleForSubItems = false ;
Color backColor = olvi . BackColor ;
Color foreColor = olvi . ForeColor ;
Font font = olvi . Font ;
foreach ( OLVListSubItem subitem in olvi . SubItems ) {
subitem . BackColor = backColor ;
subitem . ForeColor = foreColor ;
subitem . Font = font ;
}
}
/// <summary>
/// Make the list forget everything -- all rows and all columns
/// </summary>
/// <remarks>Use <see cref="ClearObjects"/> if you want to remove just the rows.</remarks>
public virtual void Reset ( ) {
this . Clear ( ) ;
this . AllColumns . Clear ( ) ;
this . ClearObjects ( ) ;
this . PrimarySortColumn = null ;
this . SecondarySortColumn = null ;
this . ClearDisabledObjects ( ) ;
this . ClearPersistentCheckState ( ) ;
this . ClearUrlVisited ( ) ;
this . ClearHotItem ( ) ;
}
#endregion
#region ISupportInitialize Members
void ISupportInitialize . BeginInit ( ) {
this . Frozen = true ;
}
void ISupportInitialize . EndInit ( ) {
if ( this . RowHeight ! = - 1 ) {
this . SmallImageList = this . SmallImageList ;
if ( this . CheckBoxes )
this . InitializeStateImageList ( ) ;
}
if ( this . UseSubItemCheckBoxes | | ( this . VirtualMode & & this . CheckBoxes ) )
this . SetupSubItemCheckBoxes ( ) ;
this . Frozen = false ;
}
#endregion
#region Image list manipulation
/// <summary>
/// Update our externally visible image list so it holds the same images as our shadow list, but sized correctly
/// </summary>
private void SetupBaseImageList ( ) {
// If a row height hasn't been set, or an image list has been give which is the required size, just assign it
if ( rowHeight = = - 1 | |
this . View ! = View . Details | |
( this . shadowedImageList ! = null & & this . shadowedImageList . ImageSize . Height = = rowHeight ) )
this . BaseSmallImageList = this . shadowedImageList ;
else {
int width = ( this . shadowedImageList = = null ? 16 : this . shadowedImageList . ImageSize . Width ) ;
this . BaseSmallImageList = this . MakeResizedImageList ( width , rowHeight , shadowedImageList ) ;
}
}
/// <summary>
/// Return a copy of the given source image list, where each image has been resized to be height x height in size.
/// If source is null, an empty image list of the given size is returned
/// </summary>
/// <param name="width">Height and width of the new images</param>
/// <param name="height">Height and width of the new images</param>
/// <param name="source">Source of the images (can be null)</param>
/// <returns>A new image list</returns>
private ImageList MakeResizedImageList ( int width , int height , ImageList source ) {
ImageList il = new ImageList ( ) ;
il . ImageSize = new Size ( width , height ) ;
// If there's nothing to copy, just return the new list
if ( source = = null )
return il ;
il . TransparentColor = source . TransparentColor ;
il . ColorDepth = source . ColorDepth ;
// Fill the imagelist with resized copies from the source
for ( int i = 0 ; i < source . Images . Count ; i + + ) {
Bitmap bm = this . MakeResizedImage ( width , height , source . Images [ i ] , source . TransparentColor ) ;
il . Images . Add ( bm ) ;
}
// Give each image the same key it has in the original
foreach ( String key in source . Images . Keys ) {
il . Images . SetKeyName ( source . Images . IndexOfKey ( key ) , key ) ;
}
return il ;
}
/// <summary>
/// Return a bitmap of the given height x height, which shows the given image, centred.
/// </summary>
/// <param name="width">Height and width of new bitmap</param>
/// <param name="height">Height and width of new bitmap</param>
/// <param name="image">Image to be centred</param>
/// <param name="transparent">The background color</param>
/// <returns>A new bitmap</returns>
private Bitmap MakeResizedImage ( int width , int height , Image image , Color transparent ) {
Bitmap bm = new Bitmap ( width , height ) ;
Graphics g = Graphics . FromImage ( bm ) ;
g . Clear ( transparent ) ;
int x = Math . Max ( 0 , ( bm . Size . Width - image . Size . Width ) / 2 ) ;
int y = Math . Max ( 0 , ( bm . Size . Height - image . Size . Height ) / 2 ) ;
g . DrawImage ( image , x , y , image . Size . Width , image . Size . Height ) ;
return bm ;
}
/// <summary>
/// Initialize the state image list with the required checkbox images
/// </summary>
protected virtual void InitializeStateImageList ( ) {
if ( this . DesignMode )
return ;
if ( ! this . CheckBoxes )
return ;
if ( this . StateImageList = = null ) {
this . StateImageList = new ImageList ( ) ;
2021-09-12 06:54:13 +00:00
this . StateImageList . ImageSize = new Size ( 16 , this . RowHeight = = - 1 ? 25 : this . RowHeight ) ;
2021-01-12 08:32:13 +00:00
this . StateImageList . ColorDepth = ColorDepth . Depth32Bit ;
}
if ( this . RowHeight ! = - 1 & &
this . View = = View . Details & &
this . StateImageList . ImageSize . Height ! = this . RowHeight ) {
this . StateImageList = new ImageList ( ) ;
this . StateImageList . ImageSize = new Size ( 16 , this . RowHeight ) ;
this . StateImageList . ColorDepth = ColorDepth . Depth32Bit ;
}
// The internal logic of ListView cycles through the state images when the primary
// checkbox is clicked. So we have to get exactly the right number of images in the
// image list.
if ( this . StateImageList . Images . Count = = 0 )
this . AddCheckStateBitmap ( this . StateImageList , UNCHECKED_KEY , CheckBoxState . UncheckedNormal ) ;
if ( this . StateImageList . Images . Count < = 1 )
this . AddCheckStateBitmap ( this . StateImageList , CHECKED_KEY , CheckBoxState . CheckedNormal ) ;
if ( this . TriStateCheckBoxes & & this . StateImageList . Images . Count < = 2 )
this . AddCheckStateBitmap ( this . StateImageList , INDETERMINATE_KEY , CheckBoxState . MixedNormal ) ;
else {
if ( this . StateImageList . Images . ContainsKey ( INDETERMINATE_KEY ) )
this . StateImageList . Images . RemoveByKey ( INDETERMINATE_KEY ) ;
}
}
/// <summary>
/// The name of the image used when a check box is checked
/// </summary>
public const string CHECKED_KEY = "checkbox-checked" ;
/// <summary>
/// The name of the image used when a check box is unchecked
/// </summary>
public const string UNCHECKED_KEY = "checkbox-unchecked" ;
/// <summary>
/// The name of the image used when a check box is Indeterminate
/// </summary>
public const string INDETERMINATE_KEY = "checkbox-indeterminate" ;
/// <summary>
/// Setup this control so it can display check boxes on subitems
/// (or primary checkboxes in virtual mode)
/// </summary>
/// <remarks>This gives the ListView a small image list, if it doesn't already have one.</remarks>
public virtual void SetupSubItemCheckBoxes ( ) {
this . ShowImagesOnSubItems = true ;
if ( this . SmallImageList = = null | | ! this . SmallImageList . Images . ContainsKey ( CHECKED_KEY ) )
this . InitializeSubItemCheckBoxImages ( ) ;
}
/// <summary>
/// Make sure the small image list for this control has checkbox images
/// (used for sub-item checkboxes).
/// </summary>
/// <remarks>
/// <para>
/// This gives the ListView a small image list, if it doesn't already have one.
/// </para>
/// <para>
/// ObjectListView has to manage checkboxes on subitems separate from the checkboxes on each row.
/// The underlying ListView knows about the per-row checkboxes, and to make them work, OLV has to
/// correctly configure the StateImageList. However, the ListView cannot do checkboxes in subitems,
/// so ObjectListView has to handle them in a differnt fashion. So, per-row checkboxes are controlled
/// by images in the StateImageList, but per-cell checkboxes are handled by images in the SmallImageList.
/// </para>
/// </remarks>
protected virtual void InitializeSubItemCheckBoxImages ( ) {
// Don't mess with the image list in design mode
if ( this . DesignMode )
return ;
ImageList il = this . SmallImageList ;
if ( il = = null ) {
il = new ImageList ( ) ;
il . ImageSize = new Size ( 16 , 16 ) ;
il . ColorDepth = ColorDepth . Depth32Bit ;
}
this . AddCheckStateBitmap ( il , CHECKED_KEY , CheckBoxState . CheckedNormal ) ;
this . AddCheckStateBitmap ( il , UNCHECKED_KEY , CheckBoxState . UncheckedNormal ) ;
this . AddCheckStateBitmap ( il , INDETERMINATE_KEY , CheckBoxState . MixedNormal ) ;
this . SmallImageList = il ;
}
private void AddCheckStateBitmap ( ImageList il , string key , CheckBoxState boxState ) {
Bitmap b = new Bitmap ( il . ImageSize . Width , il . ImageSize . Height ) ;
Graphics g = Graphics . FromImage ( b ) ;
g . Clear ( il . TransparentColor ) ;
Point location = new Point ( b . Width / 2 - 5 , b . Height / 2 - 6 ) ;
CheckBoxRenderer . DrawCheckBox ( g , location , boxState ) ;
il . Images . Add ( key , b ) ;
}
#endregion
#region Owner drawing
/// <summary>
/// Owner draw the column header
/// </summary>
/// <param name="e"></param>
protected override void OnDrawColumnHeader ( DrawListViewColumnHeaderEventArgs e ) {
e . DrawDefault = true ;
base . OnDrawColumnHeader ( e ) ;
}
/// <summary>
/// Owner draw the item
/// </summary>
/// <param name="e"></param>
protected override void OnDrawItem ( DrawListViewItemEventArgs e ) {
if ( this . View = = View . Details )
e . DrawDefault = false ;
else {
if ( this . ItemRenderer = = null )
e . DrawDefault = true ;
else {
Object row = ( ( OLVListItem ) e . Item ) . RowObject ;
e . DrawDefault = ! this . ItemRenderer . RenderItem ( e , e . Graphics , e . Bounds , row ) ;
}
}
if ( e . DrawDefault )
base . OnDrawItem ( e ) ;
}
/// <summary>
/// Owner draw a single subitem
/// </summary>
/// <param name="e"></param>
protected override void OnDrawSubItem ( DrawListViewSubItemEventArgs e ) {
//System.Diagnostics.Debug.WriteLine(String.Format("OnDrawSubItem ({0}, {1})", e.ItemIndex, e.ColumnIndex));
// Don't try to do owner drawing at design time
if ( this . DesignMode ) {
e . DrawDefault = true ;
return ;
}
object rowObject = ( ( OLVListItem ) e . Item ) . RowObject ;
// Calculate where the subitem should be drawn
Rectangle r = e . Bounds ;
// Get the special renderer for this column. If there isn't one, use the default draw mechanism.
OLVColumn column = this . GetColumn ( e . ColumnIndex ) ;
IRenderer renderer = this . GetCellRenderer ( rowObject , column ) ;
// Get a graphics context for the renderer to use.
// But we have more complications. Virtual lists have a nasty habit of drawing column 0
// whenever there is any mouse move events over a row, and doing it in an un-double-buffered manner,
// which results in nasty flickers! There are also some unbuffered draw when a mouse is first
// hovered over column 0 of a normal row. So, to avoid all complications,
// we always manually double-buffer the drawing.
// Except with Mono, which doesn't seem to handle double buffering at all :-(
BufferedGraphics buffer = BufferedGraphicsManager . Current . Allocate ( e . Graphics , r ) ;
Graphics g = buffer . Graphics ;
g . TextRenderingHint = ObjectListView . TextRenderingHint ;
g . SmoothingMode = ObjectListView . SmoothingMode ;
// Finally, give the renderer a chance to draw something
e . DrawDefault = ! renderer . RenderSubItem ( e , g , r , rowObject ) ;
if ( ! e . DrawDefault )
buffer . Render ( ) ;
buffer . Dispose ( ) ;
}
#endregion
#region OnEvent Handling
/// <summary>
/// We need the click count in the mouse up event, but that is always 1.
/// So we have to remember the click count from the preceding mouse down event.
/// </summary>
/// <param name="e"></param>
protected override void OnMouseDown ( MouseEventArgs e ) {
this . lastMouseDownClickCount = e . Clicks ;
base . OnMouseDown ( e ) ;
}
private int lastMouseDownClickCount ;
/// <summary>
/// When the mouse leaves the control, remove any hot item highlighting
/// </summary>
/// <param name="e"></param>
protected override void OnMouseLeave ( EventArgs e ) {
base . OnMouseLeave ( e ) ;
if ( ! this . Created )
return ;
this . UpdateHotItem ( new Point ( - 1 , - 1 ) ) ;
}
// We could change the hot item on the mouse hover event, but it looks wrong.
//protected override void OnMouseHover(EventArgs e) {
// System.Diagnostics.Debug.WriteLine(String.Format("OnMouseHover"));
// base.OnMouseHover(e);
// this.UpdateHotItem(this.PointToClient(Cursor.Position));
//}
/// <summary>
/// When the mouse moves, we might need to change the hot item.
/// </summary>
/// <param name="e"></param>
protected override void OnMouseMove ( MouseEventArgs e ) {
base . OnMouseMove ( e ) ;
if ( this . Created )
HandleMouseMove ( e . Location ) ;
}
internal void HandleMouseMove ( Point pt ) {
//System.Diagnostics.Debug.WriteLine(String.Format("HandleMouseMove: {0}", pt));
CellOverEventArgs args = new CellOverEventArgs ( ) ;
this . BuildCellEvent ( args , pt ) ;
this . OnCellOver ( args ) ;
this . MouseMoveHitTest = args . HitTest ;
if ( ! args . Handled )
this . UpdateHotItem ( args . HitTest ) ;
}
/// <summary>
/// Check to see if we need to start editing a cell
/// </summary>
/// <param name="e"></param>
protected override void OnMouseUp ( MouseEventArgs e ) {
//System.Diagnostics.Debug.WriteLine(String.Format("OnMouseUp"));
base . OnMouseUp ( e ) ;
if ( ! this . Created )
return ;
if ( e . Button = = MouseButtons . Right ) {
this . OnRightMouseUp ( e ) ;
return ;
}
// What event should we listen for to start cell editing?
// ------------------------------------------------------
//
// We can't use OnMouseClick, OnMouseDoubleClick, OnClick, or OnDoubleClick
// since they are not triggered for clicks on subitems without Full Row Select.
//
// We could use OnMouseDown, but selecting rows is done in OnMouseUp. This means
// that if we start the editing during OnMouseDown, the editor will automatically
// lose focus when mouse up happens.
//
// Tell the world about a cell click. If someone handles it, don't do anything else
CellClickEventArgs args = new CellClickEventArgs ( ) ;
this . BuildCellEvent ( args , e . Location ) ;
args . ClickCount = this . lastMouseDownClickCount ;
this . OnCellClick ( args ) ;
if ( args . Handled )
return ;
// Did the user click a hyperlink?
if ( this . UseHyperlinks & &
args . HitTest . HitTestLocation = = HitTestLocation . Text & &
args . SubItem ! = null & &
! String . IsNullOrEmpty ( args . SubItem . Url ) ) {
// We have to delay the running of this process otherwise we can generate
// a series of MouseUp events (don't ask me why)
this . BeginInvoke ( ( MethodInvoker ) delegate { this . ProcessHyperlinkClicked ( args ) ; } ) ;
}
// No one handled it so check to see if we should start editing.
if ( ! this . ShouldStartCellEdit ( e ) )
return ;
// We only start the edit if the user clicked on the image or text.
if ( args . HitTest . HitTestLocation = = HitTestLocation . Nothing )
return ;
// We don't edit the primary column by single clicks -- only subitems.
if ( this . CellEditActivation = = CellEditActivateMode . SingleClick & & args . ColumnIndex < = 0 )
return ;
// Don't start a cell edit operation when the user clicks on the background of a checkbox column -- it just looks wrong.
// If the user clicks on the actual checkbox, changing the checkbox state is handled elsewhere.
if ( args . Column ! = null & & args . Column . CheckBoxes )
return ;
this . EditSubItem ( args . Item , args . ColumnIndex ) ;
}
/// <summary>
/// Tell the world that a hyperlink was clicked and if the event isn't handled,
/// do the default processing.
/// </summary>
/// <param name="e"></param>
protected virtual void ProcessHyperlinkClicked ( CellClickEventArgs e ) {
HyperlinkClickedEventArgs args = new HyperlinkClickedEventArgs ( ) ;
args . HitTest = e . HitTest ;
args . ListView = this ;
args . Location = new Point ( - 1 , - 1 ) ;
args . Item = e . Item ;
args . SubItem = e . SubItem ;
args . Model = e . Model ;
args . ColumnIndex = e . ColumnIndex ;
args . Column = e . Column ;
args . RowIndex = e . RowIndex ;
args . ModifierKeys = Control . ModifierKeys ;
args . Url = e . SubItem . Url ;
this . OnHyperlinkClicked ( args ) ;
if ( ! args . Handled ) {
this . StandardHyperlinkClickedProcessing ( args ) ;
}
}
/// <summary>
/// Do the default processing for a hyperlink clicked event, which
/// is to try and open the url.
/// </summary>
/// <param name="args"></param>
protected virtual void StandardHyperlinkClickedProcessing ( HyperlinkClickedEventArgs args ) {
Cursor originalCursor = this . Cursor ;
try {
this . Cursor = Cursors . WaitCursor ;
System . Diagnostics . Process . Start ( args . Url ) ;
} catch ( Win32Exception ) {
System . Media . SystemSounds . Beep . Play ( ) ;
// ignore it
} finally {
this . Cursor = originalCursor ;
}
this . MarkUrlVisited ( args . Url ) ;
this . RefreshHotItem ( ) ;
}
/// <summary>
/// The user right clicked on the control
/// </summary>
/// <param name="e"></param>
protected virtual void OnRightMouseUp ( MouseEventArgs e ) {
CellRightClickEventArgs args = new CellRightClickEventArgs ( ) ;
this . BuildCellEvent ( args , e . Location ) ;
this . OnCellRightClick ( args ) ;
if ( ! args . Handled ) {
if ( args . MenuStrip ! = null ) {
args . MenuStrip . Show ( this , args . Location ) ;
}
}
}
internal void BuildCellEvent ( CellEventArgs args , Point location ) {
BuildCellEvent ( args , location , this . OlvHitTest ( location . X , location . Y ) ) ;
}
internal void BuildCellEvent ( CellEventArgs args , Point location , OlvListViewHitTestInfo hitTest ) {
args . HitTest = hitTest ;
args . ListView = this ;
args . Location = location ;
args . Item = hitTest . Item ;
args . SubItem = hitTest . SubItem ;
args . Model = hitTest . RowObject ;
args . ColumnIndex = hitTest . ColumnIndex ;
args . Column = hitTest . Column ;
if ( hitTest . Item ! = null )
args . RowIndex = hitTest . Item . Index ;
args . ModifierKeys = Control . ModifierKeys ;
// In non-details view, we want any hit on an item to act as if it was a hit
// on column 0 -- which, effectively, it was.
if ( args . Item ! = null & & args . ListView . View ! = View . Details ) {
args . ColumnIndex = 0 ;
args . Column = args . ListView . GetColumn ( 0 ) ;
args . SubItem = args . Item . GetSubItem ( 0 ) ;
}
}
/// <summary>
/// This method is called every time a row is selected or deselected. This can be
/// a pain if the user shift-clicks 100 rows. We override this method so we can
/// trigger one event for any number of select/deselects that come from one user action
/// </summary>
/// <param name="e"></param>
protected override void OnSelectedIndexChanged ( EventArgs e ) {
if ( this . SelectionEventsSuspended )
return ;
base . OnSelectedIndexChanged ( e ) ;
// If we haven't already scheduled an event, schedule it to be triggered
// By using idle time, we will wait until all select events for the same
// user action have finished before triggering the event.
if ( ! this . hasIdleHandler ) {
this . hasIdleHandler = true ;
this . RunWhenIdle ( HandleApplicationIdle ) ;
}
}
/// <summary>
/// Called when the handle of the underlying control is created
/// </summary>
/// <param name="e"></param>
protected override void OnHandleCreated ( EventArgs e ) {
//Debug.WriteLine("OnHandleCreated");
base . OnHandleCreated ( e ) ;
this . Invoke ( ( MethodInvoker ) this . OnControlCreated ) ;
}
/// <summary>
/// This method is called after the control has been fully created.
/// </summary>
protected virtual void OnControlCreated ( ) {
//Debug.WriteLine("OnControlCreated");
// Force the header control to be created when the listview handle is
HeaderControl hc = this . HeaderControl ;
hc . WordWrap = this . HeaderWordWrap ;
// Make sure any overlays that are set on the hot item style take effect
this . HotItemStyle = this . HotItemStyle ;
// Arrange for any group images to be installed after the control is created
NativeMethods . SetGroupImageList ( this , this . GroupImageList ) ;
this . UseExplorerTheme = this . UseExplorerTheme ;
this . RememberDisplayIndicies ( ) ;
this . SetGroupSpacing ( ) ;
if ( this . VirtualMode )
this . ApplyExtendedStyles ( ) ;
}
#endregion
#region Cell editing
/// <summary>
/// Should we start editing the cell in response to the given mouse button event?
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
protected virtual bool ShouldStartCellEdit ( MouseEventArgs e ) {
if ( this . IsCellEditing )
return false ;
if ( e . Button ! = MouseButtons . Left & & e . Button ! = MouseButtons . Right )
return false ;
if ( ( Control . ModifierKeys & ( Keys . Shift | Keys . Control | Keys . Alt ) ) ! = 0 )
return false ;
if ( this . lastMouseDownClickCount = = 1 & & (
this . CellEditActivation = = CellEditActivateMode . SingleClick | |
this . CellEditActivation = = CellEditActivateMode . SingleClickAlways ) )
return true ;
return ( this . lastMouseDownClickCount = = 2 & & this . CellEditActivation = = CellEditActivateMode . DoubleClick ) ;
}
/// <summary>
/// Handle a key press on this control. We specifically look for F2 which edits the primary column,
/// or a Tab character during an edit operation, which tries to start editing on the next (or previous) cell.
/// </summary>
/// <param name="keyData"></param>
/// <returns></returns>
protected override bool ProcessDialogKey ( Keys keyData ) {
if ( this . IsCellEditing )
return this . CellEditKeyEngine . HandleKey ( this , keyData ) ;
// Treat F2 as a request to edit the primary column
if ( keyData = = Keys . F2 ) {
this . EditSubItem ( ( OLVListItem ) this . FocusedItem , 0 ) ;
return base . ProcessDialogKey ( keyData ) ;
}
// Treat Ctrl-C as Copy To Clipboard.
if ( this . CopySelectionOnControlC & & keyData = = ( Keys . C | Keys . Control ) ) {
this . CopySelectionToClipboard ( ) ;
return true ;
}
// Treat Ctrl-A as Select All.
if ( this . SelectAllOnControlA & & keyData = = ( Keys . A | Keys . Control ) ) {
this . SelectAll ( ) ;
return true ;
}
return base . ProcessDialogKey ( keyData ) ;
}
/// <summary>
/// Start an editing operation on the first editable column of the given model.
/// </summary>
/// <param name="rowModel"></param>
/// <remarks>
/// <para>
/// If the model doesn't exist, or there are no editable columns, this method
/// will do nothing.</para>
/// <para>
/// This will start an edit operation regardless of CellActivationMode.
/// </para>
/// </remarks>
public virtual void EditModel ( object rowModel ) {
OLVListItem olvItem = this . ModelToItem ( rowModel ) ;
if ( olvItem = = null )
return ;
for ( int i = 0 ; i < olvItem . SubItems . Count ; i + + ) {
if ( this . GetColumn ( i ) . IsEditable ) {
this . StartCellEdit ( olvItem , i ) ;
return ;
}
}
}
/// <summary>
/// Begin an edit operation on the given cell.
/// </summary>
/// <remarks>This performs various sanity checks and passes off the real work to StartCellEdit().</remarks>
/// <param name="item">The row to be edited</param>
/// <param name="subItemIndex">The index of the cell to be edited</param>
public virtual void EditSubItem ( OLVListItem item , int subItemIndex ) {
if ( item = = null )
return ;
if ( subItemIndex < 0 & & subItemIndex > = item . SubItems . Count )
return ;
if ( this . CellEditActivation = = CellEditActivateMode . None )
return ;
if ( ! this . GetColumn ( subItemIndex ) . IsEditable )
return ;
if ( ! item . Enabled )
return ;
this . StartCellEdit ( item , subItemIndex ) ;
}
/// <summary>
/// Really start an edit operation on a given cell. The parameters are assumed to be sane.
/// </summary>
/// <param name="item">The row to be edited</param>
/// <param name="subItemIndex">The index of the cell to be edited</param>
public virtual void StartCellEdit ( OLVListItem item , int subItemIndex ) {
OLVColumn column = this . GetColumn ( subItemIndex ) ;
Control c = this . GetCellEditor ( item , subItemIndex ) ;
Rectangle cellBounds = this . CalculateCellBounds ( item , subItemIndex ) ;
2021-01-23 15:35:30 +00:00
//c.Bounds = this.CalculateCellEditorBounds(item, subItemIndex, c.PreferredSize);
c . Bounds = cellBounds ;
2021-01-12 08:32:13 +00:00
// Try to align the control as the column is aligned. Not all controls support this property
Munger . PutProperty ( c , "TextAlign" , column . TextAlign ) ;
// Give the control the value from the model
this . SetControlValue ( c , column . GetValue ( item . RowObject ) , column . GetStringValue ( item . RowObject ) ) ;
// Give the outside world the chance to munge with the process
this . CellEditEventArgs = new CellEditEventArgs ( column , c , cellBounds , item , subItemIndex ) ;
this . OnCellEditStarting ( this . CellEditEventArgs ) ;
if ( this . CellEditEventArgs . Cancel )
return ;
// The event handler may have completely changed the control, so we need to remember it
this . cellEditor = this . CellEditEventArgs . Control ;
this . Invalidate ( ) ;
this . Controls . Add ( this . cellEditor ) ;
this . ConfigureControl ( ) ;
this . PauseAnimations ( true ) ;
}
private Control cellEditor ;
internal CellEditEventArgs CellEditEventArgs ;
/// <summary>
/// Calculate the bounds of the edit control for the given item/column
/// </summary>
/// <param name="item"></param>
/// <param name="subItemIndex"></param>
/// <param name="preferredSize"> </param>
/// <returns></returns>
public Rectangle CalculateCellEditorBounds ( OLVListItem item , int subItemIndex , Size preferredSize ) {
Rectangle r = CalculateCellBounds ( item , subItemIndex ) ;
// Calculate the width of the cell's current contents
return this . OwnerDraw
? CalculateCellEditorBoundsOwnerDrawn ( item , subItemIndex , r , preferredSize )
: CalculateCellEditorBoundsStandard ( item , subItemIndex , r , preferredSize ) ;
}
/// <summary>
/// Calculate the bounds of the edit control for the given item/column, when the listview
/// is being owner drawn.
/// </summary>
/// <param name="item"></param>
/// <param name="subItemIndex"></param>
/// <param name="r"></param>
/// <param name="preferredSize"> </param>
/// <returns>A rectangle that is the bounds of the cell editor</returns>
protected Rectangle CalculateCellEditorBoundsOwnerDrawn ( OLVListItem item , int subItemIndex , Rectangle r , Size preferredSize ) {
IRenderer renderer = this . View = = View . Details
? this . GetCellRenderer ( item . RowObject , this . GetColumn ( subItemIndex ) )
: this . ItemRenderer ;
if ( renderer = = null )
return r ;
using ( Graphics g = this . CreateGraphics ( ) ) {
return renderer . GetEditRectangle ( g , r , item , subItemIndex , preferredSize ) ;
}
}
/// <summary>
/// Calculate the bounds of the edit control for the given item/column, when the listview
/// is not being owner drawn.
/// </summary>
/// <param name="item"></param>
/// <param name="subItemIndex"></param>
/// <param name="cellBounds"></param>
/// <param name="preferredSize"> </param>
/// <returns>A rectangle that is the bounds of the cell editor</returns>
protected Rectangle CalculateCellEditorBoundsStandard ( OLVListItem item , int subItemIndex , Rectangle cellBounds , Size preferredSize ) {
if ( this . View = = View . Tile )
return cellBounds ;
// Center the editor vertically
if ( cellBounds . Height ! = preferredSize . Height )
cellBounds . Y + = ( cellBounds . Height - preferredSize . Height ) / 2 ;
// Only Details view needs more processing
if ( this . View ! = View . Details )
return cellBounds ;
// Allow for image (if there is one).
int offset = 0 ;
object imageSelector = null ;
if ( subItemIndex = = 0 )
imageSelector = item . ImageSelector ;
else {
// We only check for subitem images if we are owner drawn or showing subitem images
if ( this . OwnerDraw | | this . ShowImagesOnSubItems )
imageSelector = item . GetSubItem ( subItemIndex ) . ImageSelector ;
}
if ( this . GetActualImageIndex ( imageSelector ) ! = - 1 ) {
offset + = this . SmallImageSize . Width + 2 ;
}
// Allow for checkbox
if ( this . CheckBoxes & & this . StateImageList ! = null & & subItemIndex = = 0 ) {
offset + = this . StateImageList . ImageSize . Width + 2 ;
}
// Allow for indent (first column only)
if ( subItemIndex = = 0 & & item . IndentCount > 0 ) {
offset + = ( this . SmallImageSize . Width * item . IndentCount ) ;
}
// Do the adjustment
if ( offset > 0 ) {
cellBounds . X + = offset ;
cellBounds . Width - = offset ;
}
return cellBounds ;
}
/// <summary>
/// Try to give the given value to the provided control. Fall back to assigning a string
/// if the value assignment fails.
/// </summary>
/// <param name="control">A control</param>
/// <param name="value">The value to be given to the control</param>
/// <param name="stringValue">The string to be given if the value doesn't work</param>
protected virtual void SetControlValue ( Control control , Object value , String stringValue ) {
// Handle combobox explicitly
ComboBox cb = control as ComboBox ;
if ( cb ! = null ) {
if ( cb . Created )
cb . SelectedValue = value ;
else
this . BeginInvoke ( new MethodInvoker ( delegate {
cb . SelectedValue = value ;
} ) ) ;
return ;
}
if ( Munger . PutProperty ( control , "Value" , value ) )
return ;
// There wasn't a Value property, or we couldn't set it, so set the text instead
try
{
String valueAsString = value as String ;
control . Text = valueAsString ? ? stringValue ;
}
catch ( ArgumentOutOfRangeException ) {
// The value couldn't be set via the Text property.
}
}
/// <summary>
/// Setup the given control to be a cell editor
/// </summary>
protected virtual void ConfigureControl ( ) {
this . cellEditor . Validating + = new CancelEventHandler ( CellEditor_Validating ) ;
this . cellEditor . Select ( ) ;
}
/// <summary>
/// Return the value that the given control is showing
/// </summary>
/// <param name="control"></param>
/// <returns></returns>
protected virtual Object GetControlValue ( Control control ) {
if ( control = = null )
return null ;
TextBox box = control as TextBox ;
if ( box ! = null )
return box . Text ;
ComboBox comboBox = control as ComboBox ;
if ( comboBox ! = null )
return comboBox . SelectedValue ;
CheckBox checkBox = control as CheckBox ;
if ( checkBox ! = null )
return checkBox . Checked ;
try {
return control . GetType ( ) . InvokeMember ( "Value" , BindingFlags . GetProperty , null , control , null ) ;
} catch ( MissingMethodException ) { // Microsoft throws this
return control . Text ;
} catch ( MissingFieldException ) { // Mono throws this
return control . Text ;
}
}
/// <summary>
/// Called when the cell editor could be about to lose focus. Time to commit the change
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void CellEditor_Validating ( object sender , CancelEventArgs e ) {
this . CellEditEventArgs . Cancel = false ;
this . CellEditEventArgs . NewValue = this . GetControlValue ( this . cellEditor ) ;
this . OnCellEditorValidating ( this . CellEditEventArgs ) ;
if ( this . CellEditEventArgs . Cancel ) {
this . CellEditEventArgs . Control . Select ( ) ;
e . Cancel = true ;
} else
FinishCellEdit ( ) ;
}
/// <summary>
/// Return the bounds of the given cell
/// </summary>
/// <param name="item">The row to be edited</param>
/// <param name="subItemIndex">The index of the cell to be edited</param>
/// <returns>A Rectangle</returns>
public virtual Rectangle CalculateCellBounds ( OLVListItem item , int subItemIndex ) {
// It seems on Win7, GetSubItemBounds() does not have the same problems with
// column 0 that it did previously.
// TODO - Check on XP
if ( this . View ! = View . Details )
return this . GetItemRect ( item . Index , ItemBoundsPortion . Label ) ;
Rectangle r = item . GetSubItemBounds ( subItemIndex ) ;
r . Width - = 1 ;
r . Height - = 1 ;
return r ;
// We use ItemBoundsPortion.Label rather than ItemBoundsPortion.Item
// since Label extends to the right edge of the cell, whereas Item gives just the
// current text width.
//return this.CalculateCellBounds(item, subItemIndex, ItemBoundsPortion.Label);
}
/// <summary>
/// Return the bounds of the given cell only until the edge of the current text
/// </summary>
/// <param name="item">The row to be edited</param>
/// <param name="subItemIndex">The index of the cell to be edited</param>
/// <returns>A Rectangle</returns>
public virtual Rectangle CalculateCellTextBounds ( OLVListItem item , int subItemIndex ) {
return this . CalculateCellBounds ( item , subItemIndex , ItemBoundsPortion . ItemOnly ) ;
}
private Rectangle CalculateCellBounds ( OLVListItem item , int subItemIndex , ItemBoundsPortion portion ) {
// SubItem.Bounds works for every subitem, except the first.
if ( subItemIndex > 0 )
return item . GetSubItemBounds ( subItemIndex ) ;
// For non detail views, we just use the requested portion
Rectangle r = this . GetItemRect ( item . Index , portion ) ;
if ( r . Y < - 10000000 | | r . Y > 10000000 ) {
r . Y = item . Bounds . Y ;
}
if ( this . View ! = View . Details )
return r ;
// Finding the bounds of cell 0 should not be a difficult task, but it is. Problems:
// 1) item.SubItem[0].Bounds is always the full bounds of the entire row, not just cell 0.
// 2) if column 0 has been dragged to some other position, the bounds always has a left edge of 0.
// We avoid both these problems by using the position of sides the column header to calculate
// the sides of the cell
Point sides = NativeMethods . GetScrolledColumnSides ( this , 0 ) ;
r . X = sides . X + 4 ;
r . Width = sides . Y - sides . X - 5 ;
return r ;
}
/// <summary>
/// Calculate the visible bounds of the given column. The column's bottom edge is
/// either the bottom of the last row or the bottom of the control.
/// </summary>
/// <param name="bounds">The bounds of the control itself</param>
/// <param name="column">The column</param>
/// <returns>A Rectangle</returns>
/// <remarks>This returns an empty rectnage if the control isn't in Details mode,
/// OR has doesn't have any rows, OR if the given column is hidden.</remarks>
public virtual Rectangle CalculateColumnVisibleBounds ( Rectangle bounds , OLVColumn column )
{
// Sanity checks
if ( column = = null | |
this . View ! = System . Windows . Forms . View . Details | |
this . GetItemCount ( ) = = 0 | |
! column . IsVisible )
return Rectangle . Empty ;
Point sides = NativeMethods . GetScrolledColumnSides ( this , column . Index ) ;
if ( sides . X = = - 1 )
return Rectangle . Empty ;
Rectangle columnBounds = new Rectangle ( sides . X , bounds . Top , sides . Y - sides . X , bounds . Bottom ) ;
// Find the bottom of the last item. The column only extends to there.
OLVListItem lastItem = this . GetLastItemInDisplayOrder ( ) ;
if ( lastItem ! = null )
{
Rectangle lastItemBounds = lastItem . Bounds ;
if ( ! lastItemBounds . IsEmpty & & lastItemBounds . Bottom < columnBounds . Bottom )
columnBounds . Height = lastItemBounds . Bottom - columnBounds . Top ;
}
return columnBounds ;
}
/// <summary>
/// Return a control that can be used to edit the value of the given cell.
/// </summary>
/// <param name="item">The row to be edited</param>
/// <param name="subItemIndex">The index of the cell to be edited</param>
/// <returns>A Control to edit the given cell</returns>
protected virtual Control GetCellEditor ( OLVListItem item , int subItemIndex ) {
OLVColumn column = this . GetColumn ( subItemIndex ) ;
Object value = column . GetValue ( item . RowObject ) ? ? this . GetFirstNonNullValue ( column ) ;
// TODO: What do we do if value is still null here?
// Ask the registry for an instance of the appropriate editor.
// Use a default editor if the registry can't create one for us.
Control editor = ObjectListView . EditorRegistry . GetEditor ( item . RowObject , column , value ) ? ?
this . MakeDefaultCellEditor ( column ) ;
return editor ;
}
/// <summary>
/// Get the first non-null value of the given column.
/// At most 1000 rows will be considered.
/// </summary>
/// <param name="column"></param>
/// <returns>The first non-null value, or null if no non-null values were found</returns>
internal object GetFirstNonNullValue ( OLVColumn column ) {
for ( int i = 0 ; i < Math . Min ( this . GetItemCount ( ) , 1000 ) ; i + + ) {
object value = column . GetValue ( this . GetModelObject ( i ) ) ;
if ( value ! = null )
return value ;
}
return null ;
}
/// <summary>
/// Return a TextBox that can be used as a default cell editor.
/// </summary>
/// <param name="column">What column does the cell belong to?</param>
/// <returns></returns>
protected virtual Control MakeDefaultCellEditor ( OLVColumn column ) {
TextBox tb = new TextBox ( ) ;
if ( column . AutoCompleteEditor )
this . ConfigureAutoComplete ( tb , column ) ;
return tb ;
}
/// <summary>
/// Configure the given text box to autocomplete unique values
/// from the given column. At most 1000 rows will be considered.
/// </summary>
/// <param name="tb">The textbox to configure</param>
/// <param name="column">The column used to calculate values</param>
public void ConfigureAutoComplete ( TextBox tb , OLVColumn column ) {
this . ConfigureAutoComplete ( tb , column , 1000 ) ;
}
/// <summary>
/// Configure the given text box to autocomplete unique values
/// from the given column. At most 1000 rows will be considered.
/// </summary>
/// <param name="tb">The textbox to configure</param>
/// <param name="column">The column used to calculate values</param>
/// <param name="maxRows">Consider only this many rows</param>
public void ConfigureAutoComplete ( TextBox tb , OLVColumn column , int maxRows ) {
// Don't consider more rows than we actually have
maxRows = Math . Min ( this . GetItemCount ( ) , maxRows ) ;
// Reset any existing autocomplete
tb . AutoCompleteCustomSource . Clear ( ) ;
// CONSIDER: Should we use ClusteringStrategy here?
// Build a list of unique values, to be used as autocomplete on the editor
Dictionary < string , bool > alreadySeen = new Dictionary < string , bool > ( ) ;
List < string > values = new List < string > ( ) ;
for ( int i = 0 ; i < maxRows ; i + + ) {
string valueAsString = column . GetStringValue ( this . GetModelObject ( i ) ) ;
if ( ! String . IsNullOrEmpty ( valueAsString ) & & ! alreadySeen . ContainsKey ( valueAsString ) ) {
values . Add ( valueAsString ) ;
alreadySeen [ valueAsString ] = true ;
}
}
tb . AutoCompleteCustomSource . AddRange ( values . ToArray ( ) ) ;
tb . AutoCompleteSource = AutoCompleteSource . CustomSource ;
tb . AutoCompleteMode = column . AutoCompleteEditorMode ;
}
/// <summary>
/// Stop editing a cell and throw away any changes.
/// </summary>
public virtual void CancelCellEdit ( ) {
if ( ! this . IsCellEditing )
return ;
// Let the world know that the user has cancelled the edit operation
this . CellEditEventArgs . Cancel = true ;
this . CellEditEventArgs . NewValue = this . GetControlValue ( this . cellEditor ) ;
this . OnCellEditFinishing ( this . CellEditEventArgs ) ;
// Now cleanup the editing process
this . CleanupCellEdit ( false , this . CellEditEventArgs . AutoDispose ) ;
}
/// <summary>
/// If a cell edit is in progress, finish the edit.
/// </summary>
/// <returns>Returns false if the finishing process was cancelled
/// (i.e. the cell editor is still on screen)</returns>
/// <remarks>This method does not guarantee that the editing will finish. The validation
/// process can cause the finishing to be aborted. Developers should check the return value
/// or use IsCellEditing property after calling this method to see if the user is still
/// editing a cell.</remarks>
public virtual bool PossibleFinishCellEditing ( ) {
return this . PossibleFinishCellEditing ( false ) ;
}
/// <summary>
/// If a cell edit is in progress, finish the edit.
/// </summary>
/// <returns>Returns false if the finishing process was cancelled
/// (i.e. the cell editor is still on screen)</returns>
/// <remarks>This method does not guarantee that the editing will finish. The validation
/// process can cause the finishing to be aborted. Developers should check the return value
/// or use IsCellEditing property after calling this method to see if the user is still
/// editing a cell.</remarks>
/// <param name="expectingCellEdit">True if it is likely that another cell is going to be
/// edited immediately after this cell finishes editing</param>
public virtual bool PossibleFinishCellEditing ( bool expectingCellEdit ) {
if ( ! this . IsCellEditing )
return true ;
this . CellEditEventArgs . Cancel = false ;
this . CellEditEventArgs . NewValue = this . GetControlValue ( this . cellEditor ) ;
this . OnCellEditorValidating ( this . CellEditEventArgs ) ;
if ( this . CellEditEventArgs . Cancel )
return false ;
this . FinishCellEdit ( expectingCellEdit ) ;
return true ;
}
/// <summary>
/// Finish the cell edit operation, writing changed data back to the model object
/// </summary>
/// <remarks>This method does not trigger a Validating event, so it always finishes
/// the cell edit.</remarks>
public virtual void FinishCellEdit ( ) {
this . FinishCellEdit ( false ) ;
}
/// <summary>
/// Finish the cell edit operation, writing changed data back to the model object
/// </summary>
/// <remarks>This method does not trigger a Validating event, so it always finishes
/// the cell edit.</remarks>
/// <param name="expectingCellEdit">True if it is likely that another cell is going to be
/// edited immediately after this cell finishes editing</param>
public virtual void FinishCellEdit ( bool expectingCellEdit ) {
if ( ! this . IsCellEditing )
return ;
this . CellEditEventArgs . Cancel = false ;
this . CellEditEventArgs . NewValue = this . GetControlValue ( this . cellEditor ) ;
this . OnCellEditFinishing ( this . CellEditEventArgs ) ;
// If someone doesn't cancel the editing process, write the value back into the model
if ( ! this . CellEditEventArgs . Cancel ) {
this . CellEditEventArgs . Column . PutValue ( this . CellEditEventArgs . RowObject , this . CellEditEventArgs . NewValue ) ;
this . RefreshItem ( this . CellEditEventArgs . ListViewItem ) ;
}
this . CleanupCellEdit ( expectingCellEdit , this . CellEditEventArgs . AutoDispose ) ;
// Tell the world that the cell has been edited
this . OnCellEditFinished ( this . CellEditEventArgs ) ;
}
/// <summary>
/// Remove all trace of any existing cell edit operation
/// </summary>
/// <param name="expectingCellEdit">True if it is likely that another cell is going to be
/// edited immediately after this cell finishes editing</param>
/// <param name="disposeOfCellEditor">True if the cell editor should be disposed </param>
protected virtual void CleanupCellEdit ( bool expectingCellEdit , bool disposeOfCellEditor ) {
if ( this . cellEditor = = null )
return ;
this . cellEditor . Validating - = new CancelEventHandler ( CellEditor_Validating ) ;
Control soonToBeOldCellEditor = this . cellEditor ;
this . cellEditor = null ;
// Delay cleaning up the cell editor so that if we are immediately going to
// start a new cell edit (because the user pressed Tab) the new cell editor
// has a chance to grab the focus. Without this, the ListView gains focus
// momentarily (after the cell editor is remove and before the new one is created)
// causing the list's selection to flash momentarily.
EventHandler toBeRun = null ;
toBeRun = delegate ( object sender , EventArgs e ) {
Application . Idle - = toBeRun ;
this . Controls . Remove ( soonToBeOldCellEditor ) ;
if ( disposeOfCellEditor )
soonToBeOldCellEditor . Dispose ( ) ;
this . Invalidate ( ) ;
if ( ! this . IsCellEditing ) {
if ( this . Focused )
this . Select ( ) ;
this . PauseAnimations ( false ) ;
}
} ;
// We only want to delay the removal of the control if we are expecting another cell
// to be edited. Otherwise, we remove the control immediately.
if ( expectingCellEdit )
this . RunWhenIdle ( toBeRun ) ;
else
toBeRun ( null , null ) ;
}
#endregion
#region Hot row and cell handling
/// <summary>
/// Force the hot item to be recalculated
/// </summary>
public virtual void ClearHotItem ( ) {
this . UpdateHotItem ( new Point ( - 1 , - 1 ) ) ;
}
/// <summary>
/// Force the hot item to be recalculated
/// </summary>
public virtual void RefreshHotItem ( ) {
this . UpdateHotItem ( this . PointToClient ( Cursor . Position ) ) ;
}
/// <summary>
/// The mouse has moved to the given pt. See if the hot item needs to be updated
/// </summary>
/// <param name="pt">Where is the mouse?</param>
/// <remarks>This is the main entry point for hot item handling</remarks>
protected virtual void UpdateHotItem ( Point pt ) {
this . UpdateHotItem ( this . OlvHitTest ( pt . X , pt . Y ) ) ;
}
/// <summary>
/// The mouse has moved to the given pt. See if the hot item needs to be updated
/// </summary>
/// <param name="hti"></param>
/// <remarks>This is the main entry point for hot item handling</remarks>
protected virtual void UpdateHotItem ( OlvListViewHitTestInfo hti ) {
// We only need to do the work of this method when the list has hot parts
// (i.e. some element whose visual appearance changes when under the mouse)?
// Hot item decorations and hyperlinks are obvious, but if we have checkboxes
// or buttons, those are also "hot". It's difficult to quickly detect if there are any
// columns that have checkboxes or buttons, so we just abdicate responsibililty and
// provide a property (UseHotControls) which lets the programmer say whether to do
// the hot processing or not.
if ( ! this . UseHotItem & & ! this . UseHyperlinks & & ! this . UseHotControls )
return ;
int newHotRow = hti . RowIndex ;
int newHotColumn = hti . ColumnIndex ;
HitTestLocation newHotCellHitLocation = hti . HitTestLocation ;
HitTestLocationEx newHotCellHitLocationEx = hti . HitTestLocationEx ;
OLVGroup newHotGroup = hti . Group ;
// In non-details view, we treat any hit on a row as if it were a hit
// on column 0 -- which (effectively) it is!
if ( newHotRow > = 0 & & this . View ! = View . Details )
newHotColumn = 0 ;
if ( this . HotRowIndex = = newHotRow & &
this . HotColumnIndex = = newHotColumn & &
this . HotCellHitLocation = = newHotCellHitLocation & &
this . HotCellHitLocationEx = = newHotCellHitLocationEx & &
this . HotGroup = = newHotGroup ) {
return ;
}
// Trigger the hotitem changed event
HotItemChangedEventArgs args = new HotItemChangedEventArgs ( ) ;
args . HotCellHitLocation = newHotCellHitLocation ;
args . HotCellHitLocationEx = newHotCellHitLocationEx ;
args . HotColumnIndex = newHotColumn ;
args . HotRowIndex = newHotRow ;
args . HotGroup = newHotGroup ;
args . OldHotCellHitLocation = this . HotCellHitLocation ;
args . OldHotCellHitLocationEx = this . HotCellHitLocationEx ;
args . OldHotColumnIndex = this . HotColumnIndex ;
args . OldHotRowIndex = this . HotRowIndex ;
args . OldHotGroup = this . HotGroup ;
this . OnHotItemChanged ( args ) ;
// Update the state of the control
this . HotRowIndex = newHotRow ;
this . HotColumnIndex = newHotColumn ;
this . HotCellHitLocation = newHotCellHitLocation ;
this . HotCellHitLocationEx = newHotCellHitLocationEx ;
this . HotGroup = newHotGroup ;
// If the event handler handled it complete, don't do anything else
if ( args . Handled )
return ;
// System.Diagnostics.Debug.WriteLine(String.Format("Changed hot item: {0}", args));
this . BeginUpdate ( ) ;
try {
this . Invalidate ( ) ;
if ( args . OldHotRowIndex ! = - 1 )
this . UnapplyHotItem ( args . OldHotRowIndex ) ;
if ( this . HotRowIndex ! = - 1 ) {
// Virtual lists apply hot item style when fetching their rows
if ( this . VirtualMode ) {
this . ClearCachedInfo ( ) ;
this . RedrawItems ( this . HotRowIndex , this . HotRowIndex , true ) ;
} else {
this . UpdateHotRow ( this . HotRowIndex , this . HotColumnIndex , this . HotCellHitLocation , hti . Item ) ;
}
}
if ( this . UseHotItem & & this . HotItemStyleOrDefault . Overlay ! = null ) {
this . RefreshOverlays ( ) ;
}
}
finally {
this . EndUpdate ( ) ;
}
}
/// <summary>
/// Update the given row using the current hot item information
/// </summary>
/// <param name="olvi"></param>
protected virtual void UpdateHotRow ( OLVListItem olvi ) {
this . UpdateHotRow ( this . HotRowIndex , this . HotColumnIndex , this . HotCellHitLocation , olvi ) ;
}
/// <summary>
/// Update the given row using the given hot item information
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="columnIndex"></param>
/// <param name="hitLocation"></param>
/// <param name="olvi"></param>
protected virtual void UpdateHotRow ( int rowIndex , int columnIndex , HitTestLocation hitLocation , OLVListItem olvi ) {
if ( rowIndex < 0 | | columnIndex < 0 )
return ;
// System.Diagnostics.Debug.WriteLine(String.Format("UpdateHotRow: {0}, {1}, {2}", rowIndex, columnIndex, hitLocation));
if ( this . UseHyperlinks ) {
OLVColumn column = this . GetColumn ( columnIndex ) ;
OLVListSubItem subItem = olvi . GetSubItem ( columnIndex ) ;
if ( column . Hyperlink & & hitLocation = = HitTestLocation . Text & & ! String . IsNullOrEmpty ( subItem . Url ) ) {
this . ApplyCellStyle ( olvi , columnIndex , this . HyperlinkStyle . Over ) ;
this . Cursor = this . HyperlinkStyle . OverCursor ? ? Cursors . Default ;
} else {
this . Cursor = Cursors . Default ;
}
}
if ( this . UseHotItem ) {
if ( ! olvi . Selected & & olvi . Enabled ) {
this . ApplyRowStyle ( olvi , this . HotItemStyleOrDefault ) ;
}
}
}
/// <summary>
/// Apply a style to the given row
/// </summary>
/// <param name="olvi"></param>
/// <param name="style"></param>
public virtual void ApplyRowStyle ( OLVListItem olvi , IItemStyle style ) {
if ( style = = null )
return ;
Font font = style . Font ? ? olvi . Font ;
if ( style . FontStyle ! = FontStyle . Regular )
font = new Font ( font ? ? this . Font , style . FontStyle ) ;
if ( ! Equals ( font , olvi . Font ) ) {
if ( olvi . UseItemStyleForSubItems )
olvi . Font = font ;
else {
foreach ( ListViewItem . ListViewSubItem x in olvi . SubItems )
x . Font = font ;
}
}
if ( ! style . ForeColor . IsEmpty ) {
if ( olvi . UseItemStyleForSubItems )
olvi . ForeColor = style . ForeColor ;
else {
foreach ( ListViewItem . ListViewSubItem x in olvi . SubItems )
x . ForeColor = style . ForeColor ;
}
}
if ( ! style . BackColor . IsEmpty ) {
if ( olvi . UseItemStyleForSubItems )
olvi . BackColor = style . BackColor ;
else {
foreach ( ListViewItem . ListViewSubItem x in olvi . SubItems )
x . BackColor = style . BackColor ;
}
}
}
/// <summary>
/// Apply a style to a cell
/// </summary>
/// <param name="olvi"></param>
/// <param name="columnIndex"></param>
/// <param name="style"></param>
protected virtual void ApplyCellStyle ( OLVListItem olvi , int columnIndex , IItemStyle style ) {
if ( style = = null )
return ;
// Don't apply formatting to subitems when not in Details view
if ( this . View ! = View . Details & & columnIndex > 0 )
return ;
olvi . UseItemStyleForSubItems = false ;
ListViewItem . ListViewSubItem subItem = olvi . SubItems [ columnIndex ] ;
if ( style . Font ! = null )
subItem . Font = style . Font ;
if ( style . FontStyle ! = FontStyle . Regular )
subItem . Font = new Font ( subItem . Font ? ? olvi . Font ? ? this . Font , style . FontStyle ) ;
if ( ! style . ForeColor . IsEmpty )
subItem . ForeColor = style . ForeColor ;
if ( ! style . BackColor . IsEmpty )
subItem . BackColor = style . BackColor ;
}
/// <summary>
/// Remove hot item styling from the given row
/// </summary>
/// <param name="index"></param>
protected virtual void UnapplyHotItem ( int index ) {
this . Cursor = Cursors . Default ;
// Virtual lists will apply the appropriate formatting when the row is fetched
if ( this . VirtualMode ) {
if ( index < this . VirtualListSize )
this . RedrawItems ( index , index , true ) ;
} else {
OLVListItem olvi = this . GetItem ( index ) ;
if ( olvi ! = null ) {
//this.PostProcessOneRow(index, index, olvi);
this . RefreshItem ( olvi ) ;
}
}
}
#endregion
#region Drag and drop
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnItemDrag ( ItemDragEventArgs e ) {
base . OnItemDrag ( e ) ;
if ( this . DragSource = = null )
return ;
Object data = this . DragSource . StartDrag ( this , e . Button , ( OLVListItem ) e . Item ) ;
if ( data ! = null ) {
DragDropEffects effect = this . DoDragDrop ( data , this . DragSource . GetAllowedEffects ( data ) ) ;
this . DragSource . EndDrag ( data , effect ) ;
}
}
/// <summary>
///
/// </summary>
/// <param name="args"></param>
protected override void OnDragEnter ( DragEventArgs args ) {
base . OnDragEnter ( args ) ;
if ( this . DropSink ! = null )
this . DropSink . Enter ( args ) ;
}
/// <summary>
///
/// </summary>
/// <param name="args"></param>
protected override void OnDragOver ( DragEventArgs args ) {
base . OnDragOver ( args ) ;
if ( this . DropSink ! = null )
this . DropSink . Over ( args ) ;
}
/// <summary>
///
/// </summary>
/// <param name="args"></param>
protected override void OnDragDrop ( DragEventArgs args ) {
base . OnDragDrop ( args ) ;
if ( this . DropSink ! = null )
this . DropSink . Drop ( args ) ;
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnDragLeave ( EventArgs e ) {
base . OnDragLeave ( e ) ;
if ( this . DropSink ! = null )
this . DropSink . Leave ( ) ;
}
/// <summary>
///
/// </summary>
/// <param name="args"></param>
protected override void OnGiveFeedback ( GiveFeedbackEventArgs args ) {
base . OnGiveFeedback ( args ) ;
if ( this . DropSink ! = null )
this . DropSink . GiveFeedback ( args ) ;
}
/// <summary>
///
/// </summary>
/// <param name="args"></param>
protected override void OnQueryContinueDrag ( QueryContinueDragEventArgs args ) {
base . OnQueryContinueDrag ( args ) ;
if ( this . DropSink ! = null )
this . DropSink . QueryContinue ( args ) ;
}
#endregion
#region Decorations and Overlays
/// <summary>
/// Add the given decoration to those on this list and make it appear
/// </summary>
/// <param name="decoration">The decoration</param>
/// <remarks>
/// A decoration scrolls with the listview. An overlay stays fixed in place.
/// </remarks>
public virtual void AddDecoration ( IDecoration decoration ) {
if ( decoration = = null )
return ;
this . Decorations . Add ( decoration ) ;
this . Invalidate ( ) ;
}
/// <summary>
/// Add the given overlay to those on this list and make it appear
/// </summary>
/// <param name="overlay">The overlay</param>
public virtual void AddOverlay ( IOverlay overlay ) {
if ( overlay = = null )
return ;
this . Overlays . Add ( overlay ) ;
this . Invalidate ( ) ;
}
/// <summary>
/// Draw all the decorations
/// </summary>
/// <param name="g">A Graphics</param>
/// <param name="itemsThatWereRedrawn">The items that were redrawn and whose decorations should also be redrawn</param>
protected virtual void DrawAllDecorations ( Graphics g , List < OLVListItem > itemsThatWereRedrawn ) {
g . TextRenderingHint = ObjectListView . TextRenderingHint ;
g . SmoothingMode = ObjectListView . SmoothingMode ;
Rectangle contentRectangle = this . ContentRectangle ;
if ( this . HasEmptyListMsg & & this . GetItemCount ( ) = = 0 ) {
this . EmptyListMsgOverlay . Draw ( this , g , contentRectangle ) ;
}
// Let the drop sink draw whatever feedback it likes
if ( this . DropSink ! = null ) {
this . DropSink . DrawFeedback ( g , contentRectangle ) ;
}
// Draw our item and subitem decorations
foreach ( OLVListItem olvi in itemsThatWereRedrawn ) {
if ( olvi . HasDecoration ) {
foreach ( IDecoration d in olvi . Decorations ) {
d . ListItem = olvi ;
d . SubItem = null ;
d . Draw ( this , g , contentRectangle ) ;
}
}
foreach ( OLVListSubItem subItem in olvi . SubItems ) {
if ( subItem . HasDecoration ) {
foreach ( IDecoration d in subItem . Decorations ) {
d . ListItem = olvi ;
d . SubItem = subItem ;
d . Draw ( this , g , contentRectangle ) ;
}
}
}
if ( this . SelectedRowDecoration ! = null & & olvi . Selected & & olvi . Enabled ) {
this . SelectedRowDecoration . ListItem = olvi ;
this . SelectedRowDecoration . SubItem = null ;
this . SelectedRowDecoration . Draw ( this , g , contentRectangle ) ;
}
}
// Now draw the specifically registered decorations
foreach ( IDecoration decoration in this . Decorations ) {
decoration . ListItem = null ;
decoration . SubItem = null ;
decoration . Draw ( this , g , contentRectangle ) ;
}
// Finally, draw any hot item decoration
if ( this . UseHotItem ) {
IDecoration hotItemDecoration = this . HotItemStyleOrDefault . Decoration ;
if ( hotItemDecoration ! = null ) {
hotItemDecoration . ListItem = this . GetItem ( this . HotRowIndex ) ;
if ( hotItemDecoration . ListItem = = null | | hotItemDecoration . ListItem . Enabled ) {
hotItemDecoration . SubItem = hotItemDecoration . ListItem = = null ? null : hotItemDecoration . ListItem . GetSubItem ( this . HotColumnIndex ) ;
hotItemDecoration . Draw ( this , g , contentRectangle ) ;
}
}
}
// If we are in design mode, we don't want to use the glass panels,
// so we draw the background overlays here
if ( this . DesignMode ) {
foreach ( IOverlay overlay in this . Overlays ) {
overlay . Draw ( this , g , contentRectangle ) ;
}
}
}
/// <summary>
/// Is the given decoration shown on this list
/// </summary>
/// <param name="decoration">The overlay</param>
public virtual bool HasDecoration ( IDecoration decoration ) {
return this . Decorations . Contains ( decoration ) ;
}
/// <summary>
/// Is the given overlay shown on this list?
/// </summary>
/// <param name="overlay">The overlay</param>
public virtual bool HasOverlay ( IOverlay overlay ) {
return this . Overlays . Contains ( overlay ) ;
}
/// <summary>
/// Hide any overlays.
/// </summary>
/// <remarks>
/// This is only a temporary hiding -- the overlays will be shown
/// the next time the ObjectListView redraws.
/// </remarks>
public virtual void HideOverlays ( ) {
foreach ( GlassPanelForm glassPanel in this . glassPanels ) {
glassPanel . HideGlass ( ) ;
}
}
/// <summary>
/// Create and configure the empty list msg overlay
/// </summary>
protected virtual void InitializeEmptyListMsgOverlay ( ) {
TextOverlay overlay = new TextOverlay ( ) ;
overlay . Alignment = System . Drawing . ContentAlignment . MiddleCenter ;
overlay . TextColor = SystemColors . ControlDarkDark ;
overlay . BackColor = Color . BlanchedAlmond ;
overlay . BorderColor = SystemColors . ControlDark ;
overlay . BorderWidth = 2.0f ;
this . EmptyListMsgOverlay = overlay ;
}
/// <summary>
/// Initialize the standard image and text overlays
/// </summary>
protected virtual void InitializeStandardOverlays ( ) {
this . OverlayImage = new ImageOverlay ( ) ;
this . AddOverlay ( this . OverlayImage ) ;
this . OverlayText = new TextOverlay ( ) ;
this . AddOverlay ( this . OverlayText ) ;
}
/// <summary>
/// Make sure that any overlays are visible.
/// </summary>
public virtual void ShowOverlays ( ) {
// If we shouldn't show overlays, then don't create glass panels
if ( ! this . ShouldShowOverlays ( ) )
return ;
// Make sure that each overlay has its own glass panels
if ( this . Overlays . Count ! = this . glassPanels . Count ) {
foreach ( IOverlay overlay in this . Overlays ) {
GlassPanelForm glassPanel = this . FindGlassPanelForOverlay ( overlay ) ;
if ( glassPanel = = null ) {
glassPanel = new GlassPanelForm ( ) ;
glassPanel . Bind ( this , overlay ) ;
this . glassPanels . Add ( glassPanel ) ;
}
}
}
foreach ( GlassPanelForm glassPanel in this . glassPanels ) {
glassPanel . ShowGlass ( ) ;
}
}
private bool ShouldShowOverlays ( ) {
// If we are in design mode, we dont show the overlays
if ( this . DesignMode )
return false ;
// If we are explicitly not using overlays, also don't show them
if ( ! this . UseOverlays )
return false ;
// If there are no overlays, guess...
if ( ! this . HasOverlays )
return false ;
// If we don't have 32-bit display, alpha blending doesn't work, so again, no overlays
// TODO: This should actually figure out which screen(s) the control is on, and make sure
// that each one is 32-bit.
if ( Screen . PrimaryScreen . BitsPerPixel < 32 )
return false ;
// Finally, we can show the overlays
return true ;
}
private GlassPanelForm FindGlassPanelForOverlay ( IOverlay overlay ) {
return this . glassPanels . Find ( delegate ( GlassPanelForm x ) { return x . Overlay = = overlay ; } ) ;
}
/// <summary>
/// Refresh the display of the overlays
/// </summary>
public virtual void RefreshOverlays ( ) {
foreach ( GlassPanelForm glassPanel in this . glassPanels ) {
glassPanel . Invalidate ( ) ;
}
}
/// <summary>
/// Refresh the display of just one overlays
/// </summary>
public virtual void RefreshOverlay ( IOverlay overlay ) {
GlassPanelForm glassPanel = this . FindGlassPanelForOverlay ( overlay ) ;
if ( glassPanel ! = null )
glassPanel . Invalidate ( ) ;
}
/// <summary>
/// Remove the given decoration from this list
/// </summary>
/// <param name="decoration">The decoration to remove</param>
public virtual void RemoveDecoration ( IDecoration decoration ) {
if ( decoration = = null )
return ;
this . Decorations . Remove ( decoration ) ;
this . Invalidate ( ) ;
}
/// <summary>
/// Remove the given overlay to those on this list
/// </summary>
/// <param name="overlay">The overlay</param>
public virtual void RemoveOverlay ( IOverlay overlay ) {
if ( overlay = = null )
return ;
this . Overlays . Remove ( overlay ) ;
GlassPanelForm glassPanel = this . FindGlassPanelForOverlay ( overlay ) ;
if ( glassPanel ! = null ) {
this . glassPanels . Remove ( glassPanel ) ;
glassPanel . Unbind ( ) ;
glassPanel . Dispose ( ) ;
}
}
#endregion
#region Filtering
/// <summary>
2021-01-23 15:35:30 +00:00
/// <20> <> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1> <EFBFBD> <EFBFBD> ִ<EFBFBD> е <EFBFBD> ǰ<EFBFBD> <C7B0> װ<EFBFBD> ڿɼ<DABF> <C9BC> <EFBFBD> <EFBFBD> ϵ<EFBFBD> <CFB5> <EFBFBD> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1>
2021-01-12 08:32:13 +00:00
/// </summary>
public virtual IModelFilter CreateColumnFilter ( ) {
List < IModelFilter > filters = new List < IModelFilter > ( ) ;
foreach ( OLVColumn column in this . Columns ) {
IModelFilter filter = column . ValueBasedFilter ;
if ( filter ! = null )
filters . Add ( filter ) ;
}
return ( filters . Count = = 0 ) ? null : new CompositeAllFilter ( filters ) ;
}
/// <summary>
/// Do the actual work of filtering
/// </summary>
/// <param name="originalObjects"></param>
/// <param name="aModelFilter"></param>
/// <param name="aListFilter"></param>
/// <returns></returns>
virtual protected IEnumerable FilterObjects ( IEnumerable originalObjects , IModelFilter aModelFilter , IListFilter aListFilter ) {
// Being cautious
originalObjects = originalObjects ? ? new ArrayList ( ) ;
// Tell the world to filter the objects. If they do so, don't do anything else
// ReSharper disable PossibleMultipleEnumeration
FilterEventArgs args = new FilterEventArgs ( originalObjects ) ;
this . OnFilter ( args ) ;
if ( args . FilteredObjects ! = null )
return args . FilteredObjects ;
// Apply a filter to the list as a whole
if ( aListFilter ! = null )
originalObjects = aListFilter . Filter ( originalObjects ) ;
// Apply the object filter if there is one
if ( aModelFilter ! = null ) {
ArrayList filteredObjects = new ArrayList ( ) ;
foreach ( object model in originalObjects ) {
if ( aModelFilter . Filter ( model ) )
filteredObjects . Add ( model ) ;
}
originalObjects = filteredObjects ;
}
return originalObjects ;
// ReSharper restore PossibleMultipleEnumeration
}
/// <summary>
/// ɾ<> <C9BE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɸѡ <C9B8> <D1A1>
/// </summary>
public virtual void ResetColumnFiltering ( ) {
foreach ( OLVColumn column in this . Columns ) {
column . ValuesChosenForFiltering . Clear ( ) ;
}
this . UpdateColumnFiltering ( ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> ÿ<EFBFBD> <C3BF> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD> ֵɸѡ <C9B8> <D1A1> <EFBFBD> ´ <EFBFBD> ObjectListView<65> <77> ɸѡ
/// </summary>
public virtual void UpdateColumnFiltering ( ) {
//List<IModelFilter> filters = new List<IModelFilter>();
//IModelFilter columnFilter = this.CreateColumnFilter();
//if (columnFilter != null)
// filters.Add(columnFilter);
//if (this.AdditionalFilter != null)
// filters.Add(this.AdditionalFilter);
//this.ModelFilter = filters.Count == 0 ? null : new CompositeAllFilter(filters);
if ( this . AdditionalFilter = = null )
this . ModelFilter = this . CreateColumnFilter ( ) ;
else {
IModelFilter columnFilter = this . CreateColumnFilter ( ) ;
if ( columnFilter = = null )
this . ModelFilter = this . AdditionalFilter ;
else {
List < IModelFilter > filters = new List < IModelFilter > ( ) ;
filters . Add ( columnFilter ) ;
filters . Add ( this . AdditionalFilter ) ;
this . ModelFilter = new CompositeAllFilter ( filters ) ;
}
}
}
/// <summary>
/// When some setting related to filtering changes, this method is called.
/// </summary>
protected virtual void UpdateFiltering ( ) {
this . BuildList ( true ) ;
}
/// <summary>
/// ʹ <> õ<EFBFBD> ǰ<EFBFBD> <C7B0> װ<EFBFBD> <D7B0> ģ<EFBFBD> <EFBFBD> <CDB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ⱦ<EFBFBD> <C8BE>
/// </summary>
protected virtual void NotifyNewModelFilter ( ) {
IFilterAwareRenderer filterAware = this . DefaultRenderer as IFilterAwareRenderer ;
if ( filterAware ! = null )
filterAware . Filter = this . ModelFilter ;
foreach ( OLVColumn column in this . AllColumns ) {
filterAware = column . Renderer as IFilterAwareRenderer ;
if ( filterAware ! = null )
filterAware . Filter = this . ModelFilter ;
}
}
#endregion
#region Persistent check state
/// <summary>
/// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> <EFBFBD> ģ<EFBFBD> ͵ĸ<CDB5> ѡ <EFBFBD> <D1A1> ״̬<D7B4> <CCAC>
/// </summary>
/// <param name="model">The model</param>
/// <returns>ģ<> ͵ĸ<CDB5> ѡ <EFBFBD> <D1A1> ״̬<D7B4> <CCAC> Ĭ<EFBFBD> <C4AC> Ϊδѡ <CEB4> С <EFBFBD> </returns>
protected virtual CheckState GetPersistentCheckState ( object model ) {
CheckState state ;
if ( model ! = null & & this . CheckStateMap . TryGetValue ( model , out state ) )
return state ;
return CheckState . Unchecked ;
}
/// <summary>
/// <20> <> <EFBFBD> ø<EFBFBD> <C3B8> <EFBFBD> ģ<EFBFBD> Ͷ<EFBFBD> <CDB6> <EFBFBD> <EFBFBD> ĸ<EFBFBD> ѡ <EFBFBD> <D1A1> ״̬
/// </summary>
/// <param name="model">The model to be remembered</param>
/// <param name="state">The model's checkedness</param>
/// <returns>The state given to the method</returns>
protected virtual CheckState SetPersistentCheckState ( object model , CheckState state ) {
if ( model = = null )
return CheckState . Unchecked ;
this . CheckStateMap [ model ] = state ;
return state ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> κγ ־ø<D6BE> ѡ <EFBFBD> <D1A1> ״̬
/// </summary>
protected virtual void ClearPersistentCheckState ( ) {
this . CheckStateMap = null ;
}
#endregion
#region Implementation variables
private bool isOwnerOfObjects ; // does this ObjectListView own the Objects collection?
private bool hasIdleHandler ; // has an Idle handler already been installed?
private bool hasResizeColumnsHandler ; // has an idle handler been installed which will handle column resizing?
private bool isInWmPaintEvent ; // is a WmPaint event currently being handled?
private bool shouldDoCustomDrawing ; // should the list do its custom drawing?
private bool isMarqueSelecting ; // Is a marque selection in progress?
private int suspendSelectionEventCount ; // How many unmatched SuspendSelectionEvents() calls have been made?
private readonly List < GlassPanelForm > glassPanels = new List < GlassPanelForm > ( ) ; // The transparent panel that draws overlays
private Dictionary < string , bool > visitedUrlMap = new Dictionary < string , bool > ( ) ; // Which urls have been visited?
// TODO
//private CheckBoxSettings checkBoxSettings = new CheckBoxSettings();
#endregion
}
}