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: }