moel@345: using System;
moel@345: using System.Collections.Generic;
moel@345: using System.Collections.ObjectModel;
moel@345: using System.ComponentModel;
moel@345: using System.Drawing;
moel@345: using System.Drawing.Design;
moel@345: using System.Windows.Forms;
moel@345:
moel@345: using Aga.Controls.Tree.NodeControls;
moel@345:
moel@345: namespace Aga.Controls.Tree
moel@345: {
moel@345: public partial class TreeViewAdv
moel@345: {
moel@345: private Cursor _innerCursor = null;
moel@345:
moel@345: public override Cursor Cursor
moel@345: {
moel@345: get
moel@345: {
moel@345: if (_innerCursor != null)
moel@345: return _innerCursor;
moel@345: else
moel@345: return base.Cursor;
moel@345: }
moel@345: set
moel@345: {
moel@345: base.Cursor = value;
moel@345: }
moel@345: }
moel@345:
moel@345: #region Internal Properties
moel@345:
moel@345: private IRowLayout _rowLayout;
moel@345:
moel@345: private bool _dragMode;
moel@345: private bool DragMode
moel@345: {
moel@345: get { return _dragMode; }
moel@345: set
moel@345: {
moel@345: _dragMode = value;
moel@345: if (!value)
moel@345: {
moel@345: StopDragTimer();
moel@345: if (_dragBitmap != null)
moel@345: _dragBitmap.Dispose();
moel@345: _dragBitmap = null;
moel@345: }
moel@345: else
moel@345: StartDragTimer();
moel@345: }
moel@345: }
moel@345:
moel@345: internal int ColumnHeaderHeight
moel@345: {
moel@345: get
moel@345: {
moel@345: if (UseColumns)
moel@345: return _columnHeaderHeight;
moel@345: else
moel@345: return 0;
moel@345: }
moel@345: }
moel@345:
moel@345: ///
moel@345: /// returns all nodes, which parent is expanded
moel@345: ///
moel@345: private IEnumerable VisibleNodes
moel@345: {
moel@345: get
moel@345: {
moel@345: TreeNodeAdv node = Root;
moel@345: while (node != null)
moel@345: {
moel@345: node = node.NextVisibleNode;
moel@345: if (node != null)
moel@345: yield return node;
moel@345: }
moel@345: }
moel@345: }
moel@345:
moel@345: private bool _suspendSelectionEvent;
moel@345: internal bool SuspendSelectionEvent
moel@345: {
moel@345: get { return _suspendSelectionEvent; }
moel@345: set
moel@345: {
moel@345: if (value != _suspendSelectionEvent)
moel@345: {
moel@345: _suspendSelectionEvent = value;
moel@345: if (!_suspendSelectionEvent && _fireSelectionEvent)
moel@345: OnSelectionChanged();
moel@345: }
moel@345: }
moel@345: }
moel@345:
moel@345: private List _rowMap;
moel@345: internal List RowMap
moel@345: {
moel@345: get { return _rowMap; }
moel@345: }
moel@345:
moel@345: private TreeNodeAdv _selectionStart;
moel@345: internal TreeNodeAdv SelectionStart
moel@345: {
moel@345: get { return _selectionStart; }
moel@345: set { _selectionStart = value; }
moel@345: }
moel@345:
moel@345: private InputState _input;
moel@345: internal InputState Input
moel@345: {
moel@345: get { return _input; }
moel@345: set
moel@345: {
moel@345: _input = value;
moel@345: }
moel@345: }
moel@345:
moel@345: private bool _itemDragMode;
moel@345: internal bool ItemDragMode
moel@345: {
moel@345: get { return _itemDragMode; }
moel@345: set { _itemDragMode = value; }
moel@345: }
moel@345:
moel@345: private Point _itemDragStart;
moel@345: internal Point ItemDragStart
moel@345: {
moel@345: get { return _itemDragStart; }
moel@345: set { _itemDragStart = value; }
moel@345: }
moel@345:
moel@345:
moel@345: ///
moel@345: /// Number of rows fits to the current page
moel@345: ///
moel@345: internal int CurrentPageSize
moel@345: {
moel@345: get
moel@345: {
moel@345: return _rowLayout.CurrentPageSize;
moel@345: }
moel@345: }
moel@345:
moel@345: ///
moel@345: /// Number of all visible nodes (which parent is expanded)
moel@345: ///
moel@345: internal int RowCount
moel@345: {
moel@345: get
moel@345: {
moel@345: return RowMap.Count;
moel@345: }
moel@345: }
moel@345:
moel@345: private int _contentWidth = 0;
moel@345: private int ContentWidth
moel@345: {
moel@345: get
moel@345: {
moel@345: return _contentWidth;
moel@345: }
moel@345: }
moel@345:
moel@345: private int _firstVisibleRow;
moel@345: internal int FirstVisibleRow
moel@345: {
moel@345: get { return _firstVisibleRow; }
moel@345: set
moel@345: {
moel@345: HideEditor();
moel@345: _firstVisibleRow = value;
moel@345: UpdateView();
moel@345: }
moel@345: }
moel@345:
moel@345: private int _offsetX;
moel@345: public int OffsetX
moel@345: {
moel@345: get { return _offsetX; }
moel@345: private set
moel@345: {
moel@345: HideEditor();
moel@345: _offsetX = value;
moel@345: UpdateView();
moel@345: }
moel@345: }
moel@345:
moel@345: public override Rectangle DisplayRectangle
moel@345: {
moel@345: get
moel@345: {
moel@345: Rectangle r = ClientRectangle;
moel@345: //r.Y += ColumnHeaderHeight;
moel@345: //r.Height -= ColumnHeaderHeight;
moel@345: int w = _vScrollBar.Visible ? _vScrollBar.Width : 0;
moel@345: int h = _hScrollBar.Visible ? _hScrollBar.Height : 0;
moel@345: return new Rectangle(r.X, r.Y, r.Width - w, r.Height - h);
moel@345: }
moel@345: }
moel@345:
moel@345: private List _selection;
moel@345: internal List Selection
moel@345: {
moel@345: get { return _selection; }
moel@345: }
moel@345:
moel@345: #endregion
moel@345:
moel@345: #region Public Properties
moel@345:
moel@345: #region DesignTime
moel@345:
moel@345: private bool _shiftFirstNode;
moel@345: [DefaultValue(false), Category("Behavior")]
moel@345: public bool ShiftFirstNode
moel@345: {
moel@345: get { return _shiftFirstNode; }
moel@345: set { _shiftFirstNode = value; }
moel@345: }
moel@345:
moel@345: private bool _displayDraggingNodes;
moel@345: [DefaultValue(false), Category("Behavior")]
moel@345: public bool DisplayDraggingNodes
moel@345: {
moel@345: get { return _displayDraggingNodes; }
moel@345: set { _displayDraggingNodes = value; }
moel@345: }
moel@345:
moel@345: private bool _fullRowSelect;
moel@345: [DefaultValue(false), Category("Behavior")]
moel@345: public bool FullRowSelect
moel@345: {
moel@345: get { return _fullRowSelect; }
moel@345: set
moel@345: {
moel@345: _fullRowSelect = value;
moel@345: UpdateView();
moel@345: }
moel@345: }
moel@345:
moel@345: private bool _useColumns;
moel@345: [DefaultValue(false), Category("Behavior")]
moel@345: public bool UseColumns
moel@345: {
moel@345: get { return _useColumns; }
moel@345: set
moel@345: {
moel@345: _useColumns = value;
moel@345: FullUpdate();
moel@345: }
moel@345: }
moel@345:
moel@345: private bool _allowColumnReorder;
moel@345: [DefaultValue(false), Category("Behavior")]
moel@345: public bool AllowColumnReorder
moel@345: {
moel@345: get { return _allowColumnReorder; }
moel@345: set { _allowColumnReorder = value; }
moel@345: }
moel@345:
moel@345: private bool _showLines = true;
moel@345: [DefaultValue(true), Category("Behavior")]
moel@345: public bool ShowLines
moel@345: {
moel@345: get { return _showLines; }
moel@345: set
moel@345: {
moel@345: _showLines = value;
moel@345: UpdateView();
moel@345: }
moel@345: }
moel@345:
moel@345: private bool _showPlusMinus = true;
moel@345: [DefaultValue(true), Category("Behavior")]
moel@345: public bool ShowPlusMinus
moel@345: {
moel@345: get { return _showPlusMinus; }
moel@345: set
moel@345: {
moel@345: _showPlusMinus = value;
moel@345: FullUpdate();
moel@345: }
moel@345: }
moel@345:
moel@345: private bool _showNodeToolTips = false;
moel@345: [DefaultValue(false), Category("Behavior")]
moel@345: public bool ShowNodeToolTips
moel@345: {
moel@345: get { return _showNodeToolTips; }
moel@345: set { _showNodeToolTips = value; }
moel@345: }
moel@345:
moel@345: [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic"), DefaultValue(true), Category("Behavior"), Obsolete("No longer used")]
moel@345: public bool KeepNodesExpanded
moel@345: {
moel@345: get { return true; }
moel@345: set {}
moel@345: }
moel@345:
moel@345: private ITreeModel _model;
moel@345: ///
moel@345: /// The model associated with this .
moel@345: ///
moel@345: ///
moel@345: ///
moel@345: [Browsable(false)]
moel@345: public ITreeModel Model
moel@345: {
moel@345: get { return _model; }
moel@345: set
moel@345: {
moel@345: if (_model != value)
moel@345: {
moel@345: AbortBackgroundExpandingThreads();
moel@345: if (_model != null)
moel@345: UnbindModelEvents();
moel@345: _model = value;
moel@345: CreateNodes();
moel@345: FullUpdate();
moel@345: if (_model != null)
moel@345: BindModelEvents();
moel@345: }
moel@345: }
moel@345: }
moel@345:
moel@345: // Tahoma is the default font
moel@345: private static Font _font = new Font("Tahoma", 8.25F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)), false);
moel@345: ///
moel@345: /// The font to render content in.
moel@345: ///
moel@345: [Category("Appearance"), Description("The font to render TreeViewAdv content in.")]
moel@345: public override Font Font
moel@345: {
moel@345: get
moel@345: {
moel@345: return (base.Font);
moel@345: }
moel@345: set
moel@345: {
moel@345: if (value == null)
moel@345: base.Font = _font;
moel@345: else
moel@345: {
moel@345: if (value == DefaultFont)
moel@345: base.Font = _font;
moel@345: else
moel@345: base.Font = value;
moel@345: }
moel@345: }
moel@345: }
moel@345: public override void ResetFont()
moel@345: {
moel@345: Font = null;
moel@345: }
moel@345: private bool ShouldSerializeFont()
moel@345: {
moel@345: return (!Font.Equals(_font));
moel@345: }
moel@345: // End font property
moel@345:
moel@345: private BorderStyle _borderStyle = BorderStyle.Fixed3D;
moel@345: [DefaultValue(BorderStyle.Fixed3D), Category("Appearance")]
moel@345: public BorderStyle BorderStyle
moel@345: {
moel@345: get
moel@345: {
moel@345: return this._borderStyle;
moel@345: }
moel@345: set
moel@345: {
moel@345: if (_borderStyle != value)
moel@345: {
moel@345: _borderStyle = value;
moel@345: base.UpdateStyles();
moel@345: }
moel@345: }
moel@345: }
moel@345:
moel@345: private bool _autoRowHeight = false;
moel@345: ///
moel@345: /// Set to true to expand each row's height to fit the text of it's largest column.
moel@345: ///
moel@345: [DefaultValue(false), Category("Appearance"), Description("Expand each row's height to fit the text of it's largest column.")]
moel@345: public bool AutoRowHeight
moel@345: {
moel@345: get
moel@345: {
moel@345: return _autoRowHeight;
moel@345: }
moel@345: set
moel@345: {
moel@345: _autoRowHeight = value;
moel@345: if (value)
moel@345: _rowLayout = new AutoRowHeightLayout(this, RowHeight);
moel@345: else
moel@345: _rowLayout = new FixedRowHeightLayout(this, RowHeight);
moel@345: FullUpdate();
moel@345: }
moel@345: }
moel@345:
moel@345: private GridLineStyle _gridLineStyle = GridLineStyle.None;
moel@345: [DefaultValue(GridLineStyle.None), Category("Appearance")]
moel@345: public GridLineStyle GridLineStyle
moel@345: {
moel@345: get
moel@345: {
moel@345: return _gridLineStyle;
moel@345: }
moel@345: set
moel@345: {
moel@345: if (value != _gridLineStyle)
moel@345: {
moel@345: _gridLineStyle = value;
moel@345: UpdateView();
moel@345: OnGridLineStyleChanged();
moel@345: }
moel@345: }
moel@345: }
moel@345:
moel@345: private int _rowHeight = 16;
moel@345: [DefaultValue(16), Category("Appearance")]
moel@345: public int RowHeight
moel@345: {
moel@345: get
moel@345: {
moel@345: return _rowHeight;
moel@345: }
moel@345: set
moel@345: {
moel@345: if (value <= 0)
moel@345: throw new ArgumentOutOfRangeException("value");
moel@345:
moel@345: _rowHeight = value;
moel@345: _rowLayout.PreferredRowHeight = value;
moel@345: FullUpdate();
moel@345: }
moel@345: }
moel@345:
moel@345: private TreeSelectionMode _selectionMode = TreeSelectionMode.Single;
moel@345: [DefaultValue(TreeSelectionMode.Single), Category("Behavior")]
moel@345: public TreeSelectionMode SelectionMode
moel@345: {
moel@345: get { return _selectionMode; }
moel@345: set { _selectionMode = value; }
moel@345: }
moel@345:
moel@345: private bool _hideSelection;
moel@345: [DefaultValue(false), Category("Behavior")]
moel@345: public bool HideSelection
moel@345: {
moel@345: get { return _hideSelection; }
moel@345: set
moel@345: {
moel@345: _hideSelection = value;
moel@345: UpdateView();
moel@345: }
moel@345: }
moel@345:
moel@345: private float _topEdgeSensivity = 0.3f;
moel@345: [DefaultValue(0.3f), Category("Behavior")]
moel@345: public float TopEdgeSensivity
moel@345: {
moel@345: get { return _topEdgeSensivity; }
moel@345: set
moel@345: {
moel@345: if (value < 0 || value > 1)
moel@345: throw new ArgumentOutOfRangeException();
moel@345: _topEdgeSensivity = value;
moel@345: }
moel@345: }
moel@345:
moel@345: private float _bottomEdgeSensivity = 0.3f;
moel@345: [DefaultValue(0.3f), Category("Behavior")]
moel@345: public float BottomEdgeSensivity
moel@345: {
moel@345: get { return _bottomEdgeSensivity; }
moel@345: set
moel@345: {
moel@345: if (value < 0 || value > 1)
moel@345: throw new ArgumentOutOfRangeException("value should be from 0 to 1");
moel@345: _bottomEdgeSensivity = value;
moel@345: }
moel@345: }
moel@345:
moel@345: private bool _loadOnDemand;
moel@345: [DefaultValue(false), Category("Behavior")]
moel@345: public bool LoadOnDemand
moel@345: {
moel@345: get { return _loadOnDemand; }
moel@345: set { _loadOnDemand = value; }
moel@345: }
moel@345:
moel@345: private bool _unloadCollapsedOnReload = false;
moel@345: [DefaultValue(false), Category("Behavior")]
moel@345: public bool UnloadCollapsedOnReload
moel@345: {
moel@345: get { return _unloadCollapsedOnReload; }
moel@345: set { _unloadCollapsedOnReload = value; }
moel@345: }
moel@345:
moel@345: private int _indent = 19;
moel@345: [DefaultValue(19), Category("Behavior")]
moel@345: public int Indent
moel@345: {
moel@345: get { return _indent; }
moel@345: set
moel@345: {
moel@345: _indent = value;
moel@345: UpdateView();
moel@345: }
moel@345: }
moel@345:
moel@345: private Color _lineColor = SystemColors.ControlDark;
moel@345: [Category("Behavior")]
moel@345: public Color LineColor
moel@345: {
moel@345: get { return _lineColor; }
moel@345: set
moel@345: {
moel@345: _lineColor = value;
moel@345: CreateLinePen();
moel@345: UpdateView();
moel@345: }
moel@345: }
moel@345:
moel@345: private Color _dragDropMarkColor = Color.Black;
moel@345: [Category("Behavior")]
moel@345: public Color DragDropMarkColor
moel@345: {
moel@345: get { return _dragDropMarkColor; }
moel@345: set
moel@345: {
moel@345: _dragDropMarkColor = value;
moel@345: CreateMarkPen();
moel@345: }
moel@345: }
moel@345:
moel@345: private float _dragDropMarkWidth = 3.0f;
moel@345: [DefaultValue(3.0f), Category("Behavior")]
moel@345: public float DragDropMarkWidth
moel@345: {
moel@345: get { return _dragDropMarkWidth; }
moel@345: set
moel@345: {
moel@345: _dragDropMarkWidth = value;
moel@345: CreateMarkPen();
moel@345: }
moel@345: }
moel@345:
moel@345: private bool _highlightDropPosition = true;
moel@345: [DefaultValue(true), Category("Behavior")]
moel@345: public bool HighlightDropPosition
moel@345: {
moel@345: get { return _highlightDropPosition; }
moel@345: set { _highlightDropPosition = value; }
moel@345: }
moel@345:
moel@345: private TreeColumnCollection _columns;
moel@345: [Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
moel@345: public Collection Columns
moel@345: {
moel@345: get { return _columns; }
moel@345: }
moel@345:
moel@345: private NodeControlsCollection _controls;
moel@345: [Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
moel@345: [Editor(typeof(NodeControlCollectionEditor), typeof(UITypeEditor))]
moel@345: public Collection NodeControls
moel@345: {
moel@345: get
moel@345: {
moel@345: return _controls;
moel@345: }
moel@345: }
moel@345:
moel@345: private bool _asyncExpanding;
moel@345: ///
moel@345: /// When set to true, node contents will be read in background thread.
moel@345: ///
moel@345: [Category("Behavior"), DefaultValue(false), Description("Read children in a background thread when expanding.")]
moel@345: public bool AsyncExpanding
moel@345: {
moel@345: get { return _asyncExpanding; }
moel@345: set { _asyncExpanding = value; }
moel@345: }
moel@345:
moel@345: #endregion
moel@345:
moel@345: #region RunTime
moel@345:
moel@345: private IToolTipProvider _defaultToolTipProvider = null;
moel@345: [Browsable(false)]
moel@345: public IToolTipProvider DefaultToolTipProvider
moel@345: {
moel@345: get { return _defaultToolTipProvider; }
moel@345: set { _defaultToolTipProvider = value; }
moel@345: }
moel@345:
moel@345: [Browsable(false)]
moel@345: public IEnumerable AllNodes
moel@345: {
moel@345: get
moel@345: {
moel@345: if (_root.Nodes.Count > 0)
moel@345: {
moel@345: TreeNodeAdv node = _root.Nodes[0];
moel@345: while (node != null)
moel@345: {
moel@345: yield return node;
moel@345: if (node.Nodes.Count > 0)
moel@345: node = node.Nodes[0];
moel@345: else if (node.NextNode != null)
moel@345: node = node.NextNode;
moel@345: else
moel@345: node = node.BottomNode;
moel@345: }
moel@345: }
moel@345: }
moel@345: }
moel@345:
moel@345: private DropPosition _dropPosition;
moel@345: [Browsable(false)]
moel@345: public DropPosition DropPosition
moel@345: {
moel@345: get { return _dropPosition; }
moel@345: set { _dropPosition = value; }
moel@345: }
moel@345:
moel@345: private TreeNodeAdv _root;
moel@345: [Browsable(false)]
moel@345: public TreeNodeAdv Root
moel@345: {
moel@345: get { return _root; }
moel@345: }
moel@345:
moel@345: private ReadOnlyCollection _readonlySelection;
moel@345: [Browsable(false)]
moel@345: public ReadOnlyCollection SelectedNodes
moel@345: {
moel@345: get
moel@345: {
moel@345: return _readonlySelection;
moel@345: }
moel@345: }
moel@345:
moel@345: [Browsable(false)]
moel@345: public TreeNodeAdv SelectedNode
moel@345: {
moel@345: get
moel@345: {
moel@345: if (Selection.Count > 0)
moel@345: {
moel@345: if (CurrentNode != null && CurrentNode.IsSelected)
moel@345: return CurrentNode;
moel@345: else
moel@345: return Selection[0];
moel@345: }
moel@345: else
moel@345: return null;
moel@345: }
moel@345: set
moel@345: {
moel@345: if (SelectedNode == value)
moel@345: return;
moel@345:
moel@345: BeginUpdate();
moel@345: try
moel@345: {
moel@345: if (value == null)
moel@345: {
moel@345: ClearSelectionInternal();
moel@345: }
moel@345: else
moel@345: {
moel@345: if (!IsMyNode(value))
moel@345: throw new ArgumentException();
moel@345:
moel@345: ClearSelectionInternal();
moel@345: value.IsSelected = true;
moel@345: CurrentNode = value;
moel@345: EnsureVisible(value);
moel@345: }
moel@345: }
moel@345: finally
moel@345: {
moel@345: EndUpdate();
moel@345: }
moel@345: }
moel@345: }
moel@345:
moel@345: private TreeNodeAdv _currentNode;
moel@345: [Browsable(false)]
moel@345: public TreeNodeAdv CurrentNode
moel@345: {
moel@345: get { return _currentNode; }
moel@345: internal set { _currentNode = value; }
moel@345: }
moel@345:
moel@345: [Browsable(false)]
moel@345: public int ItemCount
moel@345: {
moel@345: get { return RowMap.Count; }
moel@345: }
moel@345:
moel@345: ///
moel@345: /// Indicates the distance the content is scrolled to the left
moel@345: ///
moel@345: [Browsable(false)]
moel@345: public int HorizontalScrollPosition
moel@345: {
moel@345: get
moel@345: {
moel@345: if (_hScrollBar.Visible)
moel@345: return _hScrollBar.Value;
moel@345: else
moel@345: return 0;
moel@345: }
moel@345: }
moel@345:
moel@345: #endregion
moel@345:
moel@345: #endregion
moel@345:
moel@345: }
moel@345: }