///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using JetBrains.Omea.Base;
using JetBrains.UI.Interop;
using SP.Windows;
namespace JetBrains.JetListViewLibrary
{
///
/// Summary description for JetListView2.
///
public class JetListView: Control
{
private JetListViewFilterCollection _filters;
private JetListViewNodeCollection _items;
private JetListViewColumnCollection _columns;
private RowListRenderer _rowListRenderer;
private RowRendererBase _baseRowRenderer;
private IRowRenderer _rowRenderer;
private HScrollBar _hScrollbar;
private VScrollBar _vScrollbar;
private SelectionModel _selectionModel;
private IControlPainter _controlPainter;
private BorderStyle _borderStyle = BorderStyle.None;
private Timer _dragScrollTimer;
private Timer _dragExpandTimer;
private Timer _inPlaceEditTimer;
private bool _dragScrollUp;
private IControlMethodInvoker _invoker;
private IInPlaceEditor _inPlaceEditor;
private IncrementalSearcher _incSearcher;
private ItemToolTip _itemToolTip;
private JetListViewNode _dragNode;
private Rectangle _dragRect;
private bool _startInPlaceEditTimer;
private Header _header;
private System.Windows.Forms.ImageList _headerImgList;
private System.ComponentModel.IContainer components;
private ColumnHeaderStyle _headerStyle = ColumnHeaderStyle.None;
private int _pendingScroll = -1;
private string _emptyText = DefaultEmptyText;
private bool _autoToolTips = true;
private bool _fullRowSelect = false;
private JetListViewPreviewColumn _autoPreviewColumn;
private bool _lastKeyDownHandled;
private IColumnSchemeProvider _columnSchemeProvider;
private IGroupProvider _groupProvider;
private SizeF _scaleFactor = new SizeF( 1.0f, 1.0f );
private Color _borderColor = Color.Black;
private Color _groupHeaderColor = SystemColors.Control;
private bool _captureFocus = false;
private bool _focusLeft = false;
private JetListViewColumn _dragOverColumn;
private bool _allowDragInsert = false;
private bool _autoRestrictDropTarget = true;
private const int _headerHeight = 18;
public const string DefaultEmptyText = "There are no items in this view.";
public JetListView()
{
_filters = new JetListViewFilterCollection();
_items = new JetListViewNodeCollection( _filters );
_columns = new JetListViewColumnCollection();
_columns.OwnerControl = this;
SetSelectionModel( new MultipleSelectionModel( _items ) );
_rowListRenderer = new RowListRenderer( _items, _selectionModel );
SetBaseRowRenderer( new SingleLineRowRenderer( _columns, _items ) );
_baseRowRenderer.RowHeight = 17;
_incSearcher = new IncrementalSearcher( _items, _rowListRenderer, _selectionModel );
_items.ChildrenRequested += HandleChildrenRequested;
_rowListRenderer.ScrollRangeChanged += HandleScrollRangeChanged;
_rowListRenderer.Invalidate += HandleInvalidateRows;
_rowListRenderer.RequestVerticalScroll += HandleRequestVerticalScroll;
InitializeComponent();
_header = new Header();
_header.Height = _headerHeight;
_header.Visible = false;
//_header.FullDragSections = true;
_header.ImageList = _headerImgList;
Controls.Add( _header );
_hScrollbar = new HScrollBar();
_hScrollbar.ValueChanged += HandleHorizontalScroll ;
_hScrollbar.SmallChange = 10;
_hScrollbar.TabStop = false;
Controls.Add( _hScrollbar );
_vScrollbar = new VScrollBar();
_vScrollbar.ValueChanged += HandleVerticalScroll;
_vScrollbar.SmallChange = _baseRowRenderer.RowHeight;
_vScrollbar.TabStop = false;
Controls.Add( _vScrollbar );
SetStyle( ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw, true );
_controlPainter = new DefaultControlPainter();
_columns.ControlPainter = _controlPainter;
_columns.Font = Font;
BackColor = SystemColors.Window;
BorderStyle = BorderStyle.Fixed3D;
_dragScrollTimer = new Timer();
_dragScrollTimer.Interval = 150;
_dragScrollTimer.Tick += HandleDragScroll;
_dragExpandTimer = new Timer();
_dragExpandTimer.Interval = 1500;
_dragExpandTimer.Tick += HandleDragExpand;
_inPlaceEditTimer = new Timer();
_inPlaceEditTimer.Interval = SystemInformation.DoubleClickTime + 10;
_inPlaceEditTimer.Tick += HandleInPlaceEditTimer;
_invoker = new ControlMethodInvoker( this );
SetRowRenderer( _baseRowRenderer );
_itemToolTip = new ItemToolTip( this );
}
protected override void Dispose( bool disposing )
{
if ( disposing )
{
_columns.Dispose();
_dragScrollTimer.Dispose();
_dragExpandTimer.Dispose();
_inPlaceEditTimer.Dispose();
_itemToolTip.Dispose();
_header.Dispose();
}
base.Dispose( disposing );
}
private void InitializeComponent()
{
components = new Container();
System.Resources.ResourceManager resources = new System.Resources.ResourceManager( typeof(JetListView) );
_headerImgList = new ImageList( components );
//
// _headerImgList
//
_headerImgList.ImageSize = new Size(14, 14);
_headerImgList.ImageStream = ((ImageListStreamer)( resources.GetObject( "_headerImgList.ImageStream" ) ) );
_headerImgList.TransparentColor = Color.Transparent;
//
// JetListView
//
Name = "JetListView";
}
///
/// Occurs when the user starts dragging an item from the list.
///
public event ItemDragEventHandler ItemDrag;
///
/// Occurs when an object is dragged over the control's bounds.
///
public new event JetListViewDragEventHandler DragOver;
///
/// Occurs when a drag-and-drop operation is completed.
///
public new event JetListViewDragEventHandler DragDrop;
///
/// Fired when a context menu is invoked on a list node.
///
public event MouseEventHandler ContextMenuInvoked;
///
/// Occurs when a list node with virtual children is expanded.
///
public event RequestChildrenEventHandler ChildrenRequested;
///
/// Occurs when a list node is double-clicked. Allows to cancel the internal
/// double-click processing of the control.
///
public new event HandledEventHandler DoubleClick;
///
/// Occurs when the UpdateItem() method is called to update an item in the control.
///
public event ItemEventHandler ItemUpdated;
///
/// Occurs when the user drags the column splitter to change the size of the column.
///
public event EventHandler ColumnResized;
///
/// Occurs when the user drags the column header to change the order of the columns.
///
public event EventHandler ColumnOrderChanged;
///
/// Occurs when the header of a column is clicked.
///
public event ColumnEventHandler ColumnClick;
public event StateChangeEventHandler SelectionStateChanged;
public event StateChangeEventHandler FocusStateChanged;
public event JetListViewNodeEventHandler ActiveNodeChanged;
protected override void ScaleCore( float dx, float dy )
{
base.ScaleCore( dx, dy );
_scaleFactor = new SizeF( dx, dy );
_vScrollbar.Width = SystemInformation.VerticalScrollBarWidth;
_hScrollbar.Height = SystemInformation.HorizontalScrollBarHeight;
UpdateBorderSize();
}
private void SetBaseRowRenderer( RowRendererBase rowRenderer )
{
if ( _baseRowRenderer != null )
{
_baseRowRenderer.ColumnClick -= ForwardColumnClick;
_baseRowRenderer.ColumnOrderChanged -= ForwardColumnOrderChanged;
_baseRowRenderer.ColumnResized -= ForwardColumnResized;
_baseRowRenderer.Dispose();
}
_baseRowRenderer = rowRenderer;
_baseRowRenderer.ColumnClick += ForwardColumnClick;
_baseRowRenderer.ColumnOrderChanged += ForwardColumnOrderChanged;
_baseRowRenderer.ColumnResized += ForwardColumnResized;
}
private void SetRowRenderer( IRowRenderer rowRenderer )
{
if ( _rowRenderer != null )
{
_rowRenderer.RequestScroll -= HandleRequestHorizontalScroll;
_rowRenderer.ScrollRangeChanged -= HandleScrollRangeChanged;
_rowRenderer.Invalidate -= HandleInvalidateAll;
_rowRenderer.HeaderControl = null;
}
_rowRenderer = rowRenderer;
_rowRenderer.RequestScroll += HandleRequestHorizontalScroll;
_rowRenderer.ScrollRangeChanged += HandleScrollRangeChanged;
_rowRenderer.Invalidate += HandleInvalidateAll;
_rowRenderer.OwnerControl = this;
_rowRenderer.HeaderControl = _header;
_rowRenderer.MethodInvoker = _invoker;
_rowRenderer.ControlPainter = _controlPainter;
_rowRenderer.FullRowSelect = _fullRowSelect;
_rowRenderer.ScrollOffset = _hScrollbar.Value;
_rowListRenderer.RowRenderer = _rowRenderer;
_incSearcher.RowRenderer = _rowRenderer;
UpdateBorderSize();
}
private void UpdateRowRenderer()
{
_baseRowRenderer.RowHeight = 17;
if ( _autoPreviewColumn == null )
{
SetRowRenderer( _baseRowRenderer );
}
else
{
AutoPreviewRowRenderer renderer = new AutoPreviewRowRenderer( _baseRowRenderer,
_autoPreviewColumn, _columns );
SetRowRenderer( renderer );
}
if ( _selectionModel.FocusNode != null )
{
_rowListRenderer.ScrollInView( _selectionModel.FocusNode );
}
}
private void HandleHorizontalScroll( object sender, EventArgs e )
{
CloseInPlaceEdit();
_rowRenderer.ScrollOffset = _hScrollbar.Value;
if ( _headerStyle != ColumnHeaderStyle.None )
{
_header.Left = _controlPainter.GetListViewBorderSize( _borderStyle ) -_hScrollbar.Value;
}
Invalidate();
}
private void CloseInPlaceEdit()
{
_inPlaceEditTimer.Stop();
if ( _inPlaceEditor != null )
{
_inPlaceEditor.CloseEdit( true );
}
}
private void HandleVerticalScroll( object sender, EventArgs e )
{
CloseInPlaceEdit();
if ( _rowListRenderer.ScrollOffset != _vScrollbar.Value )
{
_rowListRenderer.ScrollOffset = _vScrollbar.Value;
Invalidate();
}
}
private void HandleInvalidateRows( object sender, InvalidateEventArgs e )
{
Invalidate( new Rectangle( 0, e.StartY, ClientRectangle.Width, e.EndY - e.StartY ) );
}
private void HandleRequestHorizontalScroll( object sender, RequestScrollEventArgs e )
{
Trace.Assert( e.Coord >= 0 );
if ( e.Coord <= _hScrollbar.Maximum - _hScrollbar.LargeChange + 1 )
{
_hScrollbar.Value = e.Coord;
}
}
private void HandleRequestVerticalScroll( object sender, RequestScrollEventArgs e )
{
Trace.Assert( e.Coord >= 0 );
if ( e.Coord <= _vScrollbar.Maximum - _vScrollbar.LargeChange + 1 )
{
_pendingScroll = -1;
_vScrollbar.Value = e.Coord;
}
else
{
_pendingScroll = e.Coord;
}
}
private void HandleInvalidateAll( object sender, EventArgs e )
{
Invalidate();
}
public ChildNodeCollection Nodes
{
get { return _items.Nodes; }
}
public INodeCollection NodeCollection
{
get { return _items; }
}
public JetListViewNode Root
{
get { return _items.Root; }
}
public JetListViewColumnCollection Columns
{
get { return _columns; }
}
public SelectionModel Selection
{
get { return _selectionModel; }
}
public JetListViewFilterCollection Filters
{
get { return _filters; }
}
#if DEBUG
public Header Header
{
get { return _header; }
}
#endif
public IControlPainter ControlPainter
{
get { return _controlPainter; }
set
{
if ( _controlPainter != value )
{
_controlPainter = value;
_columns.ControlPainter = value;
_rowRenderer.ControlPainter = value;
UpdateBorderSize();
}
}
}
public IControlMethodInvoker ControlMethodInvoker
{
get { return _invoker; }
set
{
_invoker = value;
_rowRenderer.MethodInvoker = _invoker;
}
}
public IInPlaceEditor InPlaceEditor
{
get { return _inPlaceEditor; }
set { _inPlaceEditor = value; }
}
public BorderStyle BorderStyle
{
get { return _borderStyle; }
set
{
if ( _borderStyle != value )
{
_borderStyle = value;
UpdateBorderSize();
}
}
}
///
/// The color used for drawing the JetListView border when BorderStyle.FixedSingle is used.
///
public Color BorderColor
{
get { return _borderColor; }
set
{
if ( _borderColor != value )
{
_borderColor = value;
Invalidate();
}
}
}
public ColumnHeaderStyle HeaderStyle
{
get { return _headerStyle; }
set
{
if ( _headerStyle != value )
{
_headerStyle = value;
if ( IsHandleCreated )
{
UpdateHeaderStyle();
}
}
}
}
[DefaultValue(false)]
public bool HideSelection
{
get { return _rowListRenderer.HideSelection; }
set { _rowListRenderer.HideSelection = value; }
}
///
/// Gets or sets a value indicating whether the selection highlight covers all
/// columns in the list or just the first column.
///
[DefaultValue(false)]
public bool FullRowSelect
{
get { return _fullRowSelect; }
set
{
_fullRowSelect = value;
_rowRenderer.FullRowSelect = value;
}
}
///
/// Gets or sets a value indicating whether the user can drag column headers
/// to reorder columns in the control.
///
public bool AllowColumnReorder
{
get { return _header.AllowDragSections; }
set { _header.AllowDragSections = value; }
}
///
/// The text shown in the view when there are no visible items.
///
[DefaultValue("There are no items in this view.")]
public string EmptyText
{
get { return _emptyText; }
set { _emptyText = value; }
}
///
/// Gets or sets a value indicating whether tooltips are automatically shown
/// for columns where the displayed text is wider than the column in which
/// it is displayed.
///
[DefaultValue(true)]
public bool AutoToolTips
{
get { return _autoToolTips; }
set { _autoToolTips = value; }
}
///
/// Gets or sets the column used to draw the auto-preview text. If null, no
/// auto-preview is drawn.
///
[DefaultValue(null)]
public JetListViewPreviewColumn AutoPreviewColumn
{
get { return _autoPreviewColumn; }
set
{
if ( _autoPreviewColumn != value )
{
_autoPreviewColumn = value;
UpdateRowRenderer();
}
}
}
///
/// Gets or sets the value indicating whether the list view contents is drawn in
/// multiline mode.
///
public bool MultiLineView
{
get { return _baseRowRenderer is MultiLineRowRenderer; }
set
{
if ( value != MultiLineView )
{
if ( value )
{
MultiLineRowRenderer multiLineRenderer = new MultiLineRowRenderer( _columns );
multiLineRenderer.TopMargin = 2;
SetBaseRowRenderer( multiLineRenderer );
multiLineRenderer.ColumnSchemeProvider = _columnSchemeProvider;
}
else
{
SetBaseRowRenderer( new SingleLineRowRenderer( _columns, _items ) );
}
UpdateRowRenderer();
}
}
}
///
/// Gets or sets the column scheme which is used for all items in multiline mode.
///
[Browsable(false)]
public MultiLineColumnScheme ColumnScheme
{
get
{
if ( _columnSchemeProvider is StaticColumnSchemeProvider )
{
return _columnSchemeProvider.GetColumnScheme( null );
}
return null;
}
set
{
if ( value != null )
{
ColumnSchemeProvider = new StaticColumnSchemeProvider( value );
}
else
{
ColumnSchemeProvider = null;
}
}
}
///
/// Gets or sets the column scheme provider for displaying list view contents
/// in multiline mode.
///
public IColumnSchemeProvider ColumnSchemeProvider
{
get { return _columnSchemeProvider; }
set
{
_columnSchemeProvider = value;
if ( _baseRowRenderer is MultiLineRowRenderer )
{
(_baseRowRenderer as MultiLineRowRenderer).ColumnSchemeProvider = value;
}
}
}
///
/// Gets or sets the group provider which defines separation of items shown in the list
/// into groups.
///
public IGroupProvider GroupProvider
{
get { return _groupProvider; }
set
{
if ( !Equals( _groupProvider, value ) )
{
if ( _rowListRenderer.NodeGroupCollection != null )
{
_rowListRenderer.NodeGroupCollection.Dispose();
}
_groupProvider = value;
if ( _groupProvider != null )
{
NodeGroupCollection nodeGroupCollection = new NodeGroupCollection( _items, _groupProvider );
DefaultGroupRenderer groupRenderer = new DefaultGroupRenderer( nodeGroupCollection );
groupRenderer.ControlPainter = _controlPainter;
groupRenderer.GroupHeaderColor = _groupHeaderColor;
groupRenderer.VisibleWidth = _rowRenderer.VisibleWidth;
_rowListRenderer.GroupRenderer = groupRenderer;
_rowListRenderer.NodeGroupCollection = nodeGroupCollection;
}
else
{
_rowListRenderer.NodeGroupCollection = null;
}
UpdateVisibleNodeCollection();
_rowListRenderer.UpdateScrollRange();
Invalidate();
}
}
}
///
/// Gets or sets whether the Insert mode is allowed when dragging over the list view.
/// If yes, the drop target visual cue is drawn as an insert mark automatically when the drop-point is between the items.
///
[DefaultValue(false), Category("Behavior")]
public bool AllowDragInsert
{
get { return _allowDragInsert; }
set { _allowDragInsert = value; }
}
///
/// Gets or sets whether the drop target visual cues are painted as automatically
/// when the is set to (when dropping here is not possible).
///
[DefaultValue(true), Category("Appearance")]
public bool AutoRestrictDropTarget
{
get { return _autoRestrictDropTarget; }
set { _autoRestrictDropTarget = value; }
}
private void UpdateVisibleNodeCollection()
{
if ( _rowListRenderer != null )
{
if ( _rowListRenderer.NodeGroupCollection != null )
{
_selectionModel.VisibleNodeCollection = _rowListRenderer.NodeGroupCollection;
}
else
{
_selectionModel.VisibleNodeCollection = _items;
}
}
}
///
/// Gets or sets the value indicating whether multiple items can be selected in the list.
///
[DefaultValue(true)]
public bool MultiSelect
{
get { return _selectionModel is MultipleSelectionModel; }
set
{
if ( MultiSelect != value )
{
if ( value )
{
SetSelectionModel( new MultipleSelectionModel( _items ) );
}
else
{
SetSelectionModel( new SingleSelectionModel( _items ) );
}
}
}
}
///
/// Gets or sets the value indicating whether delimiter lines are drawn between
/// lines in the list.
///
public bool RowDelimiters
{
get { return _rowListRenderer.RowDelimiters; }
set { _rowListRenderer.RowDelimiters = value; }
}
///
/// Gets or sets the background color of unselected group headers in the view.
///
public Color GroupHeaderColor
{
get { return _groupHeaderColor; }
set
{
if ( _groupHeaderColor != value )
{
_groupHeaderColor = value;
if ( _rowListRenderer.GroupRenderer != null )
{
_rowListRenderer.GroupRenderer.GroupHeaderColor = value;
Invalidate();
}
}
}
}
private void SetSelectionModel( SelectionModel model )
{
if ( _selectionModel != null )
{
_selectionModel.ActiveNodeChanged -= ForwardActiveNodeChanged;
_selectionModel.FocusStateChanged -= ForwardFocusStateChanged;
_selectionModel.SelectionStateChanged -= ForwardSelectionStateChanged;
}
_selectionModel = model;
if ( _rowListRenderer != null )
{
_rowListRenderer.SelectionModel = _selectionModel;
}
if ( _incSearcher != null )
{
_incSearcher.SelectionModel = _selectionModel;
}
_selectionModel.ActiveNodeChanged += ForwardActiveNodeChanged;
_selectionModel.FocusStateChanged += ForwardFocusStateChanged;
_selectionModel.SelectionStateChanged += ForwardSelectionStateChanged;
UpdateVisibleNodeCollection();
Invalidate();
}
private void UpdateBorderSize()
{
PerformLayout();
int borderSize = _controlPainter.GetListViewBorderSize( _borderStyle );
if ( _rowRenderer != null )
{
_rowRenderer.BorderSize = borderSize;
}
if ( _headerStyle != ColumnHeaderStyle.None )
{
borderSize += (int) (_headerHeight * _scaleFactor.Height);
}
_rowListRenderer.BorderSize = borderSize;
Invalidate();
}
internal HScrollBar HScrollbar
{
get { return _hScrollbar; }
}
internal VScrollBar VScrollbar
{
get { return _vScrollbar; }
}
private void UpdateHeaderStyle()
{
_header.Visible = (_headerStyle != ColumnHeaderStyle.None);
_header.Clickable = (_headerStyle == ColumnHeaderStyle.Clickable);
UpdateBorderSize();
}
protected override void OnHandleCreated( EventArgs e )
{
base.OnHandleCreated( e );
_itemToolTip.CreateHandle();
if ( _headerStyle != ColumnHeaderStyle.None )
{
UpdateHeaderStyle();
}
}
protected override void OnFontChanged( EventArgs e )
{
base.OnFontChanged( e );
_columns.Font = Font;
}
protected override void OnEnabledChanged( EventArgs e )
{
base.OnEnabledChanged( e );
_rowListRenderer.ControlEnabled = Enabled;
Invalidate();
}
protected override void OnPaint( PaintEventArgs e )
{
base.OnPaint( e );
if ( _borderStyle == BorderStyle.FixedSingle )
{
using( Pen borderPen = new Pen ( _borderColor ) )
{
e.Graphics.DrawRectangle( borderPen, 0, 0, Width-1, Height-1 );
}
}
else
{
_controlPainter.DrawListViewBorder( e.Graphics, ClientRectangle, _borderStyle );
}
if ( _hScrollbar.Visible && _vScrollbar.Visible )
{
Rectangle rc = RectangleInsideBorders();
rc = new Rectangle( rc.Right - _vScrollbar.Width, rc.Bottom - _hScrollbar.Height,
_vScrollbar.Width, _hScrollbar.Height );
e.Graphics.FillRectangle( SystemBrushes.Control, rc );
}
Rectangle rcClip = InternalClientRect();
Rectangle rcPaint = e.ClipRectangle;
rcPaint.Intersect( rcClip );
e.Graphics.SetClip( rcPaint );
if ( _items.IsEmpty )
{
Rectangle rc = rcClip;
rc.Offset( 0, 20 );
StringFormat fmt = StringFormat.GenericDefault;
fmt.Alignment = StringAlignment.Center;
fmt.FormatFlags |= StringFormatFlags.NoWrap;
_controlPainter.DrawText( e.Graphics, _emptyText, Font, SystemColors.WindowText,
rc, fmt );
}
else
{
_rowListRenderer.Draw( e.Graphics, rcPaint );
}
}
internal Rectangle InternalClientRect()
{
Rectangle rcClip = RectangleInsideBorders();
if ( _vScrollbar.Visible )
{
rcClip.Width -= _vScrollbar.Width;
}
if ( _hScrollbar.Visible )
{
rcClip.Height -= _hScrollbar.Height;
}
return rcClip;
}
private Rectangle RectangleInsideBorders()
{
Rectangle rcClip = ClientRectangle;
int borderSize = _controlPainter.GetListViewBorderSize( _borderStyle );
rcClip.Inflate( -borderSize, -borderSize );
if ( _headerStyle != ColumnHeaderStyle.None )
{
rcClip.Offset( 0, (int) (_headerHeight * _scaleFactor.Height) );
rcClip.Height -= (int) (_headerHeight * _scaleFactor.Height);
}
return rcClip;
}
protected override void OnLayout( LayoutEventArgs levent )
{
base.OnLayout( levent );
UpdateScrollbars();
}
protected override void OnMouseDown( MouseEventArgs e )
{
_startInPlaceEditTimer = false;
_inPlaceEditTimer.Stop();
CloseInPlaceEdit();
bool wasFocused = ContainsFocus;
base.OnMouseDown( e );
// Mouse down outside of internal client rect?
if ( !InternalClientRect().Contains( e.X, e.Y ) )
{
return;
}
MouseHandleResult result = _rowListRenderer.HandleMouseDown( e.X, e.Y, e.Button, ModifierKeys );
// Mouse down on disposed control?
if ( IsDisposed ) // OM-11129 - subscribe wizard closes form in its mouse down handler
{
return;
}
if ( e.Button == MouseButtons.Left && e.Clicks == 1 )
{
// MouseDown: column said FocusOnMouseDown, capturing focus...
if ( ( result & MouseHandleResult.FocusOnMouseDown ) != 0 )
{
Focus();
_captureFocus = false;
}
// MouseDown: capturing mouse, expecting mouse up...
else if ( ( result & MouseHandleResult.SuppressFocus ) == 0 )
{
Capture = true;
_captureFocus = true;
}
}
if ( wasFocused && ( result & MouseHandleResult.MayInPlaceEdit) != 0 )
{
_startInPlaceEditTimer = true;
}
JetListViewNode node = _rowListRenderer.GetRowAt( e.Y );
if ( node != null )
{
Size dragSize = SystemInformation.DragSize;
_dragRect = new Rectangle( new Point( e.X - (dragSize.Width /2),
e.Y - (dragSize.Height /2)), dragSize );
_dragNode = node;
}
else
{
_dragNode = null;
}
if ( e.Clicks == 2 && e.Button == MouseButtons.Left )
{
_inPlaceEditTimer.Stop();
_startInPlaceEditTimer = false;
ProcessDoubleClick( e );
}
}
private void ProcessDoubleClick( MouseEventArgs e )
{
HandledEventArgs args = new HandledEventArgs();
if ( _rowListRenderer.AcceptDoubleClick( e.X, e.Y ) )
{
if ( DoubleClick != null )
{
DoubleClick( this, args );
}
if ( !args.Handled )
{
_rowListRenderer.HandleDoubleClick( e.X, e.Y );
}
}
}
protected virtual void OnItemDrag( MouseButtons button, object item )
{
if ( ItemDrag != null )
{
ItemDrag( this, new ItemDragEventArgs( button, item ) );
}
}
protected override void OnMouseMove( MouseEventArgs e )
{
base.OnMouseMove( e );
if ( _dragNode != null && !_dragRect.Contains( e.X, e.Y ) )
{
JetListViewNode theDragNode = _dragNode;
_dragNode = null;
_inPlaceEditTimer.Stop();
CloseInPlaceEdit();
IViewNode[] savedSelection = CheckSaveSelection( theDragNode );
OnItemDrag( e.Button, theDragNode );
CheckRestoreSelection( savedSelection );
}
_itemToolTip.UpdateToolTip( new Point( e.X, e.Y ) );
UpdateCursor();
}
protected override void OnMouseUp( MouseEventArgs e )
{
base.OnMouseUp( e );
if ( _captureFocus )
{
Focus();
_captureFocus = false;
}
_dragNode = null;
if ( _startInPlaceEditTimer )
{
_inPlaceEditTimer.Start();
}
if ( !InternalClientRect().Contains( e.X, e.Y ) )
{
return;
}
_rowListRenderer.HandleMouseUp( e.X, e.Y, e.Button, ModifierKeys );
}
protected override bool IsInputChar( char charCode )
{
return true;
}
protected override void OnLeave( EventArgs e )
{
_focusLeft = true;
base.OnLeave( e );
}
protected override void OnKeyDown( KeyEventArgs e )
{
if ( _incSearcher.HandleKeyDown( e.KeyData ) )
{
return;
}
_focusLeft = false;
base.OnKeyDown( e );
if ( e.Handled && !ContainsFocus && Form.ActiveForm == FindForm() && !_focusLeft ) // OM-7838
{
Focus();
}
if ( !e.Handled )
{
_lastKeyDownHandled = _rowListRenderer.HandleKeyDown( e );
if ( e.KeyCode == Keys.F2 && _selectionModel.ActiveNode != null )
{
InPlaceEditNode( _selectionModel.ActiveNode );
}
}
else
{
_lastKeyDownHandled = true;
}
}
protected override void OnKeyPress( KeyPressEventArgs e )
{
base.OnKeyPress( e );
if ( !_lastKeyDownHandled )
{
_incSearcher.HandleKeyPress( e.KeyChar );
}
else
{
e.Handled = true;
}
}
protected override void OnMouseWheel( MouseEventArgs e )
{
base.OnMouseWheel( e );
if ( !_vScrollbar.Visible )
return;
int lines = -e.Delta * SystemInformation.MouseWheelScrollLines / 120;
VerticalScrollClamped( _vScrollbar.Value + _rowListRenderer.GetWheelScrollDistance( lines ) );
}
private void VerticalScrollClamped( int pos )
{
if ( pos < 0 )
{
_vScrollbar.Value = 0;
}
else if ( pos > _vScrollbar.Maximum - _vScrollbar.LargeChange + 1 )
{
_vScrollbar.Value = _vScrollbar.Maximum - _vScrollbar.LargeChange + 1;
}
else
{
_vScrollbar.Value = pos;
}
}
protected override void OnGotFocus( EventArgs e )
{
base.OnGotFocus( e );
if ( _selectionModel.Count == 0 && _items.VisibleItemCount > 0 )
{
Trace.WriteLine( "JLV selecting top item from OnGotFocus" );
_selectionModel.MoveDown();
}
_rowListRenderer.ActiveSelection = true;
}
protected override void OnLostFocus( EventArgs e )
{
base.OnLostFocus( e );
_rowListRenderer.ActiveSelection = false;
_incSearcher.ClearIncrementalSearch();
_inPlaceEditTimer.Stop();
}
#region Drag'n'Drop
protected override void OnDragOver( DragEventArgs drgevent )
{
Point pnt = PointToClient( new Point( drgevent.X, drgevent.Y ) );
if ( !InternalClientRect().Contains( pnt ) )
{
drgevent.Effect = DragDropEffects.None;
return;
}
int scrollBottom = ClientSize.Height - 7;
if ( _hScrollbar.Visible )
{
scrollBottom -= _hScrollbar.Height;
}
if ( pnt.Y < 7 )
{
_dragScrollUp = true;
_dragScrollTimer.Enabled = true;
}
else if ( pnt.Y > scrollBottom )
{
_dragScrollUp = false;
_dragScrollTimer.Enabled = true;
}
else
{
_dragScrollTimer.Enabled = false;
}
// Query external handlers of their view on the drag'n'drop process
JetListViewDragEventArgs args = FillDragEventArgs(drgevent, pnt);
if ( DragOver != null )
{
DragOver( this, args );
}
// If the drop-target rendering mode is set to generic insertion, determine the proper type (above or below)
if(args.DropTargetRenderMode == DropTargetRenderMode.InsertAny)
args.DropTargetRenderMode = args.LocalY < args.RowHeight / 2 ? DropTargetRenderMode.InsertAbove : DropTargetRenderMode.InsertBelow;
// Hide the drop-target if drop is prohibited here
if((AutoRestrictDropTarget) && (args.Effect == DragDropEffects.None))
args.DropTargetRenderMode = DropTargetRenderMode.Restricted;
JetListViewNode oldDropTargetRow = _rowListRenderer.DropTargetRow;
JetListViewColumn oldDragOverColumn = _dragOverColumn;
_rowListRenderer.SetDropTarget( args.DropTargetNode, args.DropTargetRenderMode );
if ( _rowListRenderer.DropTargetRow == null )
{
_dragOverColumn = null;
}
else
{
_dragOverColumn = _rowRenderer.GetColumnAt( _rowListRenderer.DropTargetRow, pnt.X, args.LocalY );
}
if ( oldDropTargetRow != _rowListRenderer.DropTargetRow || _dragOverColumn != oldDragOverColumn )
{
_dragExpandTimer.Stop();
if ( _rowListRenderer.DropTargetRow != null && _dragOverColumn != null )
{
_dragExpandTimer.Enabled = true;
}
}
drgevent.Effect = args.Effect;
base.OnDragOver( drgevent );
}
///
/// Prepares the drag event args given the current dragging point in client coordinates.
///
internal JetListViewDragEventArgs FillDragEventArgs(DragEventArgs dea, Point pt)
{
// Get the droptarget node, and check if the drop should be Over or Insert
int localY;
int nRowTop = 0;
int nRowBottom = 0;
JetListViewNode nodeTarget = _rowListRenderer.GetRowAndDelta( pt.Y, out localY ) as JetListViewNode;
DropTargetRenderMode renderTarget = DropTargetRenderMode.Restricted;
if( nodeTarget != null )
{ // The upper and lower quarter are for Insert, and the middle area of half a row height is for Over
_rowListRenderer.GetRowBounds( nodeTarget, out nRowTop, out nRowBottom );
renderTarget = (localY < (nRowBottom - nRowTop) / 4) ? DropTargetRenderMode.InsertAbove : ((localY >= (nRowBottom - nRowTop) * 3 / 4) ? DropTargetRenderMode.InsertBelow : DropTargetRenderMode.Over);
}
return new JetListViewDragEventArgs( dea, nodeTarget, renderTarget, localY, nRowBottom - nRowTop );
}
protected override void OnDragLeave( EventArgs e )
{
EndDragOver();
base.OnDragLeave( e );
}
protected override void OnDragDrop( DragEventArgs drgevent )
{
Point pnt = PointToClient( new Point( drgevent.X, drgevent.Y ) );
EndDragOver();
JetListViewDragEventArgs dragEventArgs = FillDragEventArgs( drgevent, pnt );
if ( DragDrop != null )
{
DragDrop( this, dragEventArgs );
}
base.OnDragDrop( drgevent );
}
private void EndDragOver()
{
_dragScrollTimer.Enabled = false;
_dragExpandTimer.Enabled = false;
_rowListRenderer.ClearDropTarget();
}
private void HandleDragScroll( object sender, EventArgs e )
{
int newValue = _dragScrollUp
? _vScrollbar.Value - _vScrollbar.SmallChange
: _vScrollbar.Value + _vScrollbar.SmallChange;
VerticalScrollClamped( newValue );
}
private void HandleDragExpand( object sender, EventArgs e )
{
_dragExpandTimer.Stop();
if ( _dragOverColumn != null && _rowListRenderer.DropTargetRow != null )
{
_dragOverColumn.HandleDragHover( _rowListRenderer.DropTargetRow );
}
}
#endregion Drag'n'Drop
protected override bool IsInputKey( Keys keyData )
{
return keyData != Keys.Tab && keyData != (Keys.Shift | Keys.Tab) && keyData != Keys.Escape;
}
private void HandleScrollRangeChanged( object sender, EventArgs e )
{
if ( _invoker.InvokeRequired )
{
_invoker.BeginInvoke( new MethodInvoker( PerformLayout ) );
}
else
{
PerformLayout();
}
}
private void UpdateScrollbars()
{
if ( _rowRenderer == null || _rowListRenderer == null || _vScrollbar == null || _hScrollbar == null )
return;
if ( _controlPainter == null )
return;
SuspendLayout();
try
{
int hScrollRange = _rowRenderer.ScrollRange;
int vScrollRange = _rowListRenderer.ScrollRange;
int borderSize = _controlPainter.GetListViewBorderSize( _borderStyle );
int clientWidth = Width - 2 * borderSize;
int clientHeight = Height - 2 * borderSize;
if ( _headerStyle != ColumnHeaderStyle.None )
{
clientHeight -= (int) (_headerHeight * _scaleFactor.Height);
}
int availWidth = clientWidth;
int availHeight = clientHeight;
if ( availWidth < _vScrollbar.Width || availHeight < _hScrollbar.Height )
return;
if ( availWidth < hScrollRange )
{
availHeight = clientHeight - _hScrollbar.Height;
}
if ( availHeight < vScrollRange )
{
availWidth = clientWidth - _vScrollbar.Width;
}
// repeat the calculation because availWidth may have been reduced by previous calc
if ( availWidth < hScrollRange )
{
availHeight = clientHeight - _hScrollbar.Height;
}
if ( vScrollRange > availHeight )
{
int rowCount = availHeight / _baseRowRenderer.RowHeight;
if ( rowCount < 1 )
{
rowCount = 1;
}
int vLargeChange = rowCount * _baseRowRenderer.RowHeight;
_vScrollbar.Maximum = vScrollRange - availHeight + vLargeChange;
_vScrollbar.LargeChange = vLargeChange;
if ( _headerStyle != ColumnHeaderStyle.None )
{
_vScrollbar.Top = (int) (_headerHeight * _scaleFactor.Height) + borderSize;
}
else
{
_vScrollbar.Top = borderSize;
}
_vScrollbar.Left = Width - (borderSize+1) - _vScrollbar.Width;
_vScrollbar.Height = clientHeight - ( hScrollRange > availWidth ? _hScrollbar.Height : 0 );
if ( _vScrollbar.Value > _vScrollbar.Maximum - _vScrollbar.LargeChange + 1 )
{
_vScrollbar.Value = _vScrollbar.Maximum - _vScrollbar.LargeChange + 1;
}
_vScrollbar.Visible = true;
}
else
{
_vScrollbar.Value = 0;
_vScrollbar.Visible = false;
}
if ( hScrollRange > availWidth )
{
int hLargeChange = Math.Max( 3, availWidth - 10 );
_hScrollbar.Maximum = hScrollRange - availWidth + hLargeChange;
_hScrollbar.LargeChange = hLargeChange;
_hScrollbar.Left = borderSize;
_hScrollbar.Top = Height - (borderSize+1) - _hScrollbar.Height;
_hScrollbar.Width = clientWidth - ( _vScrollbar.Visible ? _vScrollbar.Width : 0 );
if ( _hScrollbar.Value > _hScrollbar.Maximum - _hScrollbar.LargeChange + 1 )
{
_hScrollbar.Value = _hScrollbar.Maximum - _hScrollbar.LargeChange + 1;
}
_hScrollbar.Visible = true;
}
else
{
_hScrollbar.Value = 0;
_hScrollbar.Visible = false;
}
_rowListRenderer.VisibleHeight = availHeight;
_rowRenderer.VisibleWidth = availWidth;
if ( _rowListRenderer.GroupRenderer != null )
{
_rowListRenderer.GroupRenderer.VisibleWidth = availWidth;
}
if ( _pendingScroll >= 0 && _pendingScroll <= _vScrollbar.Maximum - _vScrollbar.LargeChange + 1 )
{
_vScrollbar.Value = _pendingScroll;
}
_pendingScroll = -1;
if ( _headerStyle != ColumnHeaderStyle.None )
{
_header.Location = new Point( borderSize - _hScrollbar.Value, borderSize );
int needHeaderSize = hScrollRange;
if ( _vScrollbar.Visible )
{
needHeaderSize += _vScrollbar.Width;
}
_header.Width = Math.Max( Width - 2 * borderSize, needHeaderSize );
}
}
finally
{
ResumeLayout();
}
}
///
/// Invalidates the nodes displaying the specified item.
///
/// The item to invalidate.
public void InvalidateItem( object item )
{
JetListViewNode[] nodes = _items.NodesFromItem( item );
if ( nodes.Length == 0 )
{
throw new ArgumentException( "Item not displayed in view" );
}
for( int i=0; i
/// Updates the display of the specified item in the list.
///
/// The item to update.
/// If the item is shown in a sorted list, updates the position of the item
/// in the list. Also, if the view is filtered, updates the filtered status of the item.
/// Also invalidates the item.
public void UpdateItem( object item )
{
lock( _items )
{
DoUpdateItem( item );
}
OnItemUpdated( item );
}
private void DoUpdateItem( object item )
{
_rowRenderer.UpdateItem( item );
_items.Update( item );
InvalidateItem( item );
}
///
/// Updates the display of the specified item in the list if it is present in the list.
///
/// The item to update.
public void UpdateItemSafe( object item )
{
Guard.NullArgument( item, "item" );
lock( _items )
{
if ( !_items.Contains( item ) )
{
return;
}
DoUpdateItem( item );
}
OnItemUpdated( item );
}
private void OnItemUpdated( object item )
{
if ( ItemUpdated != null )
{
ItemUpdated( this, new ItemEventArgs( item ) );
}
}
public JetListViewNode GetNodeAt( int x, int y )
{
return _rowListRenderer.GetRowAt( y );
}
public JetListViewNode GetNodeAt( Point pnt )
{
return _rowListRenderer.GetRowAt( pnt.Y );
}
public JetListViewColumn GetColumnAt( Point pnt )
{
int deltaY;
JetListViewNode node = _rowListRenderer.GetRowAndDelta( pnt.Y, out deltaY ) as JetListViewNode;
if ( node == null )
{
return null;
}
return _rowRenderer.GetColumnAt( node, pnt.X, deltaY );
}
///
/// Returns the bounds of the cell displaying the specified column value for the specified
/// node.
///
/// The node for which the bounds are retrieved.
/// The column for which the bounds are retrieved.
/// The bounds rectangle.
public Rectangle GetItemBounds( JetListViewNode node, JetListViewColumn col )
{
int startY, endY;
Rectangle rcColBounds = _rowRenderer.GetColumnBounds( col, node );
_rowListRenderer.GetRowBounds( node, out startY, out endY );
int startX = rcColBounds.Left + col.LeftMargin;
int endX = rcColBounds.Right;
Rectangle rcClient = InternalClientRect();
endX -= col.RightMargin;
if ( endX > rcClient.Right )
{
endX = rcClient.Right;
}
return new Rectangle( rcColBounds.Left + col.LeftMargin, startY + rcColBounds.Top,
endX-startX, rcColBounds.Height );
}
protected override void WndProc( ref Message m )
{
if ( m.Msg == Win32Declarations.WM_SYSCHAR )
{
if ( _lastKeyDownHandled )
{
return;
}
}
base.WndProc( ref m );
if ( m.Msg == Win32Declarations.WM_CONTEXTMENU )
{
HandleContextMenu( m );
}
else if ( m.Msg == Win32Declarations.WM_NOTIFY )
{
NMHDR nmhdr = (NMHDR) m.GetLParam( typeof(NMHDR) );
if ( nmhdr.hwndFrom == _itemToolTip.Handle )
{
_itemToolTip.HandleWMNotify( ref m );
}
}
}
private void UpdateCursor()
{
if ( IsDisposed )
{
return;
}
Point pnt = PointToClient( Cursor.Position );
if ( InternalClientRect().Contains( pnt.X, pnt.Y ) )
{
int deltaY;
JetListViewNode node = _rowListRenderer.GetRowAndDelta( pnt.Y, out deltaY ) as JetListViewNode;
if ( node != null )
{
JetListViewColumn col = _rowRenderer.GetColumnAt( node, pnt.X, deltaY );
if ( col != null )
{
Cursor = col.GetItemCursor( node.Data );
}
}
}
}
private void HandleContextMenu( Message m )
{
_itemToolTip.Hide();
IViewNode[] savedSelection = null;
MouseButtons button = 0;
Point pnt = new Point( m.LParam.ToInt32() );
if ( pnt.X == -1 && pnt.Y == -1 )
{
pnt = GetSelectedItemMenuLocation();
}
else
{
pnt = PointToClient( pnt );
button = MouseButtons.Right;
if ( InternalClientRect().Contains( pnt.X, pnt.Y ) )
{
int deltaY;
JetListViewNode node = _rowListRenderer.GetRowAndDelta( pnt.Y, out deltaY ) as JetListViewNode;
if ( node != null )
{
savedSelection = CheckSaveSelection( node );
JetListViewColumn col = _rowRenderer.GetColumnAt( node, pnt.X, deltaY );
if ( col != null && col.HandleContextMenu( node, pnt.X, pnt.Y ) )
{
CheckRestoreSelection( savedSelection );
return;
}
}
}
}
if ( ContextMenuInvoked != null )
{
ContextMenuInvoked( this, new MouseEventArgs( button, 1, pnt.X, pnt.Y, 0 ) );
}
CheckRestoreSelection( savedSelection );
}
///
/// If the specified node is not contained in the selection, selects it and
/// returns the array containing old selection.
///
private IViewNode[] CheckSaveSelection( JetListViewNode node )
{
IViewNode[] savedSelection = null;
if ( !_selectionModel.IsNodeSelected( node ) )
{
savedSelection = _selectionModel.SelectionToArray();
_selectionModel.ClearSelection();
_selectionModel.SelectNode( node );
}
return savedSelection;
}
///
/// If the specified array is not null, restores the selection to the list
/// of nodes in the specified array.
///
private void CheckRestoreSelection( IViewNode[] savedSelection )
{
if ( savedSelection != null )
{
_selectionModel.ClearSelection();
for( int i=0; i 0 )
{
JetListViewNode node = Selection.ActiveNode;
int startY, endY;
if ( node == null || !_rowListRenderer.GetRowBounds( node, out startY, out endY ) )
{
pnt = new Point( 0, 0 );
}
else
{
pnt = new Point( 0, startY );
}
}
pnt.X += 4;
pnt.Y += 4;
return pnt;
}
private void HandleChildrenRequested( object sender, RequestChildrenEventArgs e )
{
OnChildrenRequested( e );
}
protected virtual void OnChildrenRequested( RequestChildrenEventArgs e )
{
if ( ChildrenRequested != null )
{
ChildrenRequested( this, e );
}
}
private void HandleInPlaceEditTimer( object sender, EventArgs e )
{
_inPlaceEditTimer.Stop();
if ( _selectionModel.ActiveNode != null )
{
InPlaceEditNode( _selectionModel.ActiveNode );
}
}
public void InPlaceEditNode( JetListViewNode node )
{
CloseInPlaceEdit();
if ( _inPlaceEditor != null )
{
JetListViewColumn col = _rowRenderer.GetInPlaceEditColumn( node );
if ( col == null )
return;
_items.ExpandParents( node );
_selectionModel.SelectAndFocusNode( node );
_inPlaceEditor.BeginEdit( this, col, node );
}
}
public static bool IsNodeVisible( JetListViewNode node )
{
JetListViewNode parent = node.Parent;
while( parent != null )
{
if ( parent.CollapseState == CollapseState.Collapsed )
return false;
parent = parent.Parent;
}
return true;
}
public void ScrollInView( JetListViewNode node )
{
_rowListRenderer.ScrollInView( node );
}
///
/// Scrolls in view the thread containing the specified resource.
///
/// The resource to scroll in view.
public void ScrollThreadInView( object res )
{
JetListViewNode node = _items.NodeFromItem( res );
if ( node != null )
{
int startY, endY;
if ( _rowListRenderer.GetRowBounds( node, out startY, out endY ) )
{
return;
}
JetListViewNode parent = node;
while( parent.Parent != null && parent.Parent != _items.Root )
{
parent = parent.Parent;
}
if ( parent != node )
{
_rowListRenderer.ScrollInView( parent );
}
_rowListRenderer.ScrollInView( node );
}
}
public void SetAllGroupsExpanded( bool expanded )
{
if ( _rowListRenderer.NodeGroupCollection != null )
{
_rowListRenderer.NodeGroupCollection.SetAllGroupsExpanded( expanded );
}
}
public void SetAllThreadsExpanded( bool expanded )
{
_items.SetExpandedRecursive( expanded );
}
public void CopySelection()
{
StringBuilder selBuilder = new StringBuilder();
foreach( IViewNode viewNode in _selectionModel.SelectedNodes )
{
JetListViewNode node = viewNode as JetListViewNode;
if ( node == null )
{
// skip group header nodes (OM-14696)
continue;
}
bool first = true;
foreach( JetListViewColumn col in _columns )
{
if ( col.IsIndentColumn() )
{
continue;
}
if ( first )
{
first = false;
}
else
{
selBuilder.Append( '\t' );
}
selBuilder.Append( col.GetItemText( node.Data ) );
}
selBuilder.Append( "\r\n" );
}
if ( _selectionModel.Count == 1 )
{
Clipboard.SetDataObject( selBuilder.ToString().Trim() );
}
else
{
Clipboard.SetDataObject( selBuilder.ToString() );
}
}
internal void SetEditedNode( JetListViewNode node )
{
_rowListRenderer.EditedNode = node;
}
public bool IsColumnHeaderAt( int x, int y )
{
if ( _headerStyle != ColumnHeaderStyle.None )
{
return _header.Bounds.Contains( x, y );
}
return false;
}
private void ForwardActiveNodeChanged( object sender, ViewNodeEventArgs e )
{
JetListViewNode lvNode = e.ViewNode as JetListViewNode;
if ( ActiveNodeChanged != null )
{
ActiveNodeChanged( this, new JetListViewNodeEventArgs( lvNode ) );
}
}
private void ForwardFocusStateChanged( object sender, ViewNodeStateChangeEventArgs e )
{
JetListViewNode lvNode = e.ViewNode as JetListViewNode;
if ( lvNode != null )
{
if ( FocusStateChanged != null )
{
FocusStateChanged( this, new StateChangeEventArgs( lvNode, e.State ) );
}
}
}
private void ForwardSelectionStateChanged( object sender, ViewNodeStateChangeEventArgs e )
{
JetListViewNode lvNode = e.ViewNode as JetListViewNode;
if ( lvNode != null )
{
if ( SelectionStateChanged != null )
{
SelectionStateChanged( this, new StateChangeEventArgs( lvNode, e.State ) );
}
}
}
private void ForwardColumnClick( object sender, ColumnEventArgs e )
{
if ( ColumnClick != null )
{
ColumnClick( this, e );
}
}
private void ForwardColumnOrderChanged( object sender, EventArgs e )
{
if ( ColumnOrderChanged != null )
{
ColumnOrderChanged( this, e );
}
}
private void ForwardColumnResized( object sender, EventArgs e )
{
if ( ColumnResized != null )
{
ColumnResized( this, e );
}
}
private class StaticColumnSchemeProvider: IColumnSchemeProvider
{
private readonly MultiLineColumnScheme _scheme;
public StaticColumnSchemeProvider( MultiLineColumnScheme scheme )
{
_scheme = scheme;
}
public MultiLineColumnScheme GetColumnScheme( object item )
{
return _scheme;
}
}
}
}