Пример #1
0
        /// <summary>
        /// Gets the adjacent item to the given item in the given direction.
        /// If that item is disabled, continue in that direction until an enabled item is found.
        /// </summary>
        /// <param name="olvi">The row whose neighbour is sought</param>
        /// <param name="up">The direction of the adjacentness</param>
        /// <returns>An OLVListView adjacent to the given item, or null if there are no more enabled items in that direction.</returns>
        protected OLVListItem GetAdjacentItemOrNull(OLVListItem olvi, bool up)
        {
            OLVListItem item = up ? this.ListView.GetPreviousItem(olvi) : this.ListView.GetNextItem(olvi);

            while (item != null && !item.Enabled)
            {
                item = up ? this.ListView.GetPreviousItem(item) : this.ListView.GetNextItem(item);
            }
            return(item);
        }
Пример #2
0
        /// <summary>
        /// Create a DataObject when the user does a left mouse drag operation.
        /// See IDragSource for further information.
        /// </summary>
        /// <param name="olv"></param>
        /// <param name="button"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        public virtual Object StartDrag(AdvancedListView olv, MouseButtons button, OLVListItem item)
        {
            // We only drag on left mouse
            if (button != MouseButtons.Left)
            {
                return(null);
            }

            return(this.CreateDataObject(olv));
        }
Пример #3
0
        /// <summary>
        /// Start editing the indicated cell if that cell is not already being edited
        /// </summary>
        /// <param name="olvi">The row to edit</param>
        /// <param name="subItemIndex">The cell within that row to edit</param>
        protected void StartCellEditIfDifferent(OLVListItem olvi, int subItemIndex)
        {
            if (this.ItemBeingEdited == olvi && this.SubItemIndexBeingEdited == subItemIndex)
            {
                return;
            }

            this.ListView.EnsureVisible(olvi.Index);
            this.ListView.StartCellEdit(olvi, subItemIndex);
        }
Пример #4
0
        /// <summary>
        /// Given the item and the subitem, calculate its bounds.
        /// </summary>
        /// <param name="item"></param>
        /// <param name="subItem"></param>
        /// <returns></returns>
        public virtual Rectangle CalculateItemBounds(OLVListItem item, OLVListSubItem subItem)
        {
            if (item == null)
            {
                return(Rectangle.Empty);
            }

            if (subItem == null)
            {
                return(item.Bounds);
            }

            return(item.GetSubItemBounds(item.SubItems.IndexOf(subItem)));
        }
Пример #5
0
        private static ListViewHitTestLocations ConvertNativeFlagsToDotNetLocation(OLVListItem hitItem, int flags)
        {
            // Untangle base .NET behaviour.

            // In Windows SDK, the value 8 can have two meanings here: LVHT_ONITEMSTATEICON or LVHT_ABOVE.
            // .NET changes these to be:
            // - LVHT_ABOVE becomes ListViewHitTestLocations.AboveClientArea (which is 0x100).
            // - LVHT_ONITEMSTATEICON becomes ListViewHitTestLocations.StateImage (which is 0x200).
            // So, if we see the 8 bit set in flags, we change that to either a state image hit
            // (if we hit an item) or to AboveClientAream if nothing was hit.

            if ((8 & flags) == 8)
            {
                return((ListViewHitTestLocations)(0xf7 & flags | (hitItem == null ? 0x100 : 0x200)));
            }

            // Mask off the LVHT_EX_XXXX values since ListViewHitTestLocations doesn't have them
            return((ListViewHitTestLocations)(flags & 0xffff));
        }
Пример #6
0
        /// <summary>
        /// Draw a slight colouring over our tinted column
        /// </summary>
        /// <remarks>
        /// This overlay only works when:
        /// - the list is in Details view
        /// - there is at least one row
        /// - there is a selected column (or a specified tint column)
        /// </remarks>
        /// <param name="olv"></param>
        /// <param name="g"></param>
        /// <param name="r"></param>
        public override void Draw(AdvancedListView olv, Graphics g, Rectangle r)
        {
            if (olv.View != System.Windows.Forms.View.Details)
            {
                return;
            }

            if (olv.GetItemCount() == 0)
            {
                return;
            }

            OLVColumn column = this.ColumnToTint ?? olv.SelectedColumn;

            if (column == null)
            {
                return;
            }

            Point sides = NativeMethods.GetScrolledColumnSides(olv, column.Index);

            if (sides.X == -1)
            {
                return;
            }

            Rectangle columnBounds = new Rectangle(sides.X, r.Top, sides.Y - sides.X, r.Bottom);

            // Find the bottom of the last item. The tinting should extend only to there.
            OLVListItem lastItem = olv.GetLastItemInDisplayOrder();

            if (lastItem != null)
            {
                Rectangle lastItemBounds = lastItem.Bounds;
                if (!lastItemBounds.IsEmpty && lastItemBounds.Bottom < columnBounds.Bottom)
                {
                    columnBounds.Height = lastItemBounds.Bottom - columnBounds.Top;
                }
            }
            g.FillRectangle(this.tintBrush, columnBounds);
        }
        /// <summary>
        /// Create a OlvListViewHitTestInfo
        /// </summary>
        public OlvListViewHitTestInfo(OLVListItem olvListItem, OLVListSubItem subItem, int flags, OLVGroup group, int iColumn)
        {
            item              = olvListItem;
            this.subItem      = subItem;
            location          = ConvertNativeFlagsToDotNetLocation(olvListItem, flags);
            HitTestLocationEx = (HitTestLocationEx)flags;
            Group             = group;
            ColumnIndex       = iColumn;
            ListView          = olvListItem == null ? null : (AdvancedListView)olvListItem.ListView;

            switch (location)
            {
            case ListViewHitTestLocations.StateImage:
                HitTestLocation = HitTestLocation.CheckBox;
                break;

            case ListViewHitTestLocations.Image:
                HitTestLocation = HitTestLocation.Image;
                break;

            case ListViewHitTestLocations.Label:
                HitTestLocation = HitTestLocation.Text;
                break;

            default:
                if ((HitTestLocationEx & HitTestLocationEx.LVHT_EX_GROUP_COLLAPSE) == HitTestLocationEx.LVHT_EX_GROUP_COLLAPSE)
                {
                    HitTestLocation = HitTestLocation.GroupExpander;
                }
                else if ((HitTestLocationEx & HitTestLocationEx.LVHT_EX_GROUP_MINUS_FOOTER_AND_BKGRD) != 0)
                {
                    HitTestLocation = HitTestLocation.Group;
                }
                else
                {
                    HitTestLocation = HitTestLocation.Nothing;
                }

                break;
            }
        }
Пример #8
0
 /// <summary>
 /// Gets the adjacent item to the given item in the given direction, wrapping if needed.
 /// </summary>
 /// <param name="olvi">The row whose neighbour is sought</param>
 /// <param name="up">The direction of the adjacentness</param>
 /// <returns>An OLVListView adjacent to the given item, or null if there are no more items in that direction.</returns>
 protected OLVListItem GetAdjacentItem(OLVListItem olvi, bool up)
 {
     return(this.GetAdjacentItemOrNull(olvi, up) ?? this.GetAdjacentItemOrNull(null, up));
 }
Пример #9
0
        /// <summary>
        /// Handle a change column command
        /// </summary>
        /// <param name="keyData"></param>
        /// <param name="behaviour"></param>
        protected virtual void HandleColumnChange(Keys keyData, CellEditCharacterBehaviour behaviour)
        {
            // If we couldn't finish editing the current cell, don't try to move it
            if (!this.ListView.PossibleFinishCellEditing())
            {
                return;
            }

            // Changing columns only works in details mode
            if (this.ListView.View != View.Details)
            {
                return;
            }

            List <OLVColumn> editableColumns = this.EditableColumnsInDisplayOrder;
            OLVListItem      olvi            = this.ItemBeingEdited;
            int displayIndex = Math.Max(0,
                                        editableColumns.IndexOf(this.ListView.GetColumn(this.SubItemIndexBeingEdited)));
            bool isGoingLeft = behaviour == CellEditCharacterBehaviour.ChangeColumnLeft;

            // Are we trying to continue past one of the edges?
            if ((isGoingLeft && displayIndex == 0) ||
                (!isGoingLeft && displayIndex == editableColumns.Count - 1))
            {
                // Yes, so figure out our at edge behaviour
                CellEditAtEdgeBehaviour atEdgeBehaviour;
                if (!this.CellEditKeyAtEdgeBehaviourMap.TryGetValue(keyData, out atEdgeBehaviour))
                {
                    atEdgeBehaviour = CellEditAtEdgeBehaviour.Wrap;
                }
                switch (atEdgeBehaviour)
                {
                case CellEditAtEdgeBehaviour.Ignore:
                    return;

                case CellEditAtEdgeBehaviour.EndEdit:
                    this.HandleEndEdit();
                    return;

                case CellEditAtEdgeBehaviour.ChangeRow:
                case CellEditAtEdgeBehaviour.Wrap:
                    if (atEdgeBehaviour == CellEditAtEdgeBehaviour.ChangeRow)
                    {
                        olvi = GetAdjacentItem(olvi, isGoingLeft && displayIndex == 0);
                    }
                    if (isGoingLeft)
                    {
                        displayIndex = editableColumns.Count - 1;
                    }
                    else
                    {
                        displayIndex = 0;
                    }
                    break;
                }
            }
            else
            {
                if (isGoingLeft)
                {
                    displayIndex -= 1;
                }
                else
                {
                    displayIndex += 1;
                }
            }

            int subItemIndex = editableColumns[displayIndex].Index;

            this.StartCellEditIfDifferent(olvi, subItemIndex);
        }
Пример #10
0
        /// <summary>
        /// Handle a change row command
        /// </summary>
        /// <param name="keyData"></param>
        /// <param name="behaviour"></param>
        protected virtual void HandleRowChange(Keys keyData, CellEditCharacterBehaviour behaviour)
        {
            // If we couldn't finish editing the current cell, don't try to move it
            if (!this.ListView.PossibleFinishCellEditing())
            {
                return;
            }

            OLVListItem olvi         = this.ItemBeingEdited;
            int         subItemIndex = this.SubItemIndexBeingEdited;
            bool        isGoingUp    = behaviour == CellEditCharacterBehaviour.ChangeRowUp;

            // Try to find a row above (or below) the currently edited cell
            // If we find one, start editing it and we're done.
            OLVListItem adjacentOlvi = this.GetAdjacentItemOrNull(olvi, isGoingUp);

            if (adjacentOlvi != null)
            {
                this.StartCellEditIfDifferent(adjacentOlvi, subItemIndex);
                return;
            }

            // There is no adjacent row in the direction we want, so we must be on an edge.
            CellEditAtEdgeBehaviour atEdgeBehaviour;

            if (!this.CellEditKeyAtEdgeBehaviourMap.TryGetValue(keyData, out atEdgeBehaviour))
            {
                atEdgeBehaviour = CellEditAtEdgeBehaviour.Wrap;
            }
            switch (atEdgeBehaviour)
            {
            case CellEditAtEdgeBehaviour.Ignore:
                break;

            case CellEditAtEdgeBehaviour.EndEdit:
                this.ListView.PossibleFinishCellEditing();
                break;

            case CellEditAtEdgeBehaviour.Wrap:
                adjacentOlvi = this.GetAdjacentItemOrNull(null, isGoingUp);
                this.StartCellEditIfDifferent(adjacentOlvi, subItemIndex);
                break;

            case CellEditAtEdgeBehaviour.ChangeColumn:
                // Figure out the next editable column
                List <OLVColumn> editableColumnsInDisplayOrder = this.EditableColumnsInDisplayOrder;
                int displayIndex = Math.Max(0, editableColumnsInDisplayOrder.IndexOf(this.ListView.GetColumn(subItemIndex)));
                if (isGoingUp)
                {
                    displayIndex = (editableColumnsInDisplayOrder.Count + displayIndex - 1) % editableColumnsInDisplayOrder.Count;
                }
                else
                {
                    displayIndex = (displayIndex + 1) % editableColumnsInDisplayOrder.Count;
                }
                subItemIndex = editableColumnsInDisplayOrder[displayIndex].Index;

                // Wrap to the next row and start the cell edit
                adjacentOlvi = this.GetAdjacentItemOrNull(null, isGoingUp);
                this.StartCellEditIfDifferent(adjacentOlvi, subItemIndex);
                break;
            }
        }
Пример #11
0
 /// <summary>
 /// See IDragSource documentation
 /// </summary>
 /// <param name="olv"></param>
 /// <param name="button"></param>
 /// <param name="item"></param>
 /// <returns></returns>
 public virtual object StartDrag(AdvancedListView olv, MouseButtons button, OLVListItem item)
 {
     return(null);
 }