| File: System\Windows\Forms\Controls\ListView\ListViewItem.IKeyboardToolTip.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms\System.Windows.Forms.csproj (System.Windows.Forms) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Drawing; namespace System.Windows.Forms; public partial class ListViewItem : IKeyboardToolTip { private bool AllowsToolTips => _listView?.ShowItemToolTips ?? false; bool IKeyboardToolTip.AllowsChildrenToShowToolTips() => AllowsToolTips; bool IKeyboardToolTip.AllowsToolTip() => true; bool IKeyboardToolTip.CanShowToolTipsNow() => AllowsToolTips; string IKeyboardToolTip.GetCaptionForTool(ToolTip toolTip) => ToolTipText; Rectangle IKeyboardToolTip.GetNativeScreenRectangle() => GetNativeRectangle(Index); IList<Rectangle> IKeyboardToolTip.GetNeighboringToolsRectangles() { List<Rectangle> neighboringRectangles = []; if (_listView is null) { return neighboringRectangles; } switch (_listView.View) { case View.SmallIcon: case View.LargeIcon: foreach (SearchDirectionHint searchDirectionHint in Enum.GetValues(typeof(SearchDirectionHint))) { ListViewItem? neighboringItem = FindNearestItem(searchDirectionHint); if (neighboringItem is not null) { neighboringRectangles.Add(GetNativeRectangle(neighboringItem.Index)); } } break; case View.Details: neighboringRectangles.Add(AccessibilityObject.Bounds); if (Index > 0) { neighboringRectangles.Add(_listView.Items[Index - 1].AccessibilityObject.Bounds); } if (Index < _listView.Items.Count - 1) { neighboringRectangles.Add(_listView.Items[Index + 1].AccessibilityObject.Bounds); } break; } return neighboringRectangles; } IWin32Window? IKeyboardToolTip.GetOwnerWindow() => _listView; bool IKeyboardToolTip.HasRtlModeEnabled() => _listView?.RightToLeft == RightToLeft.Yes; bool IKeyboardToolTip.IsBeingTabbedTo() => Control.AreCommonNavigationalKeysDown(); bool IKeyboardToolTip.IsHoveredWithMouse() => _listView?.AccessibilityObject.Bounds.Contains(Control.MousePosition) ?? false; void IKeyboardToolTip.OnHooked(ToolTip toolTip) => OnKeyboardToolTipHook(toolTip); void IKeyboardToolTip.OnUnhooked(ToolTip toolTip) => OnKeyboardToolTipUnhook(toolTip); bool IKeyboardToolTip.ShowsOwnToolTip() => AllowsToolTips; internal virtual void OnKeyboardToolTipHook(ToolTip toolTip) { } internal virtual void OnKeyboardToolTipUnhook(ToolTip toolTip) { } private Rectangle GetNativeRectangle(int index) { if (_listView is null) { return Rectangle.Empty; } ListViewItem item = _listView.Items[index]; if (item.Group is not null && item.Group.CollapsedState == ListViewGroupCollapsedState.Collapsed) { return Rectangle.Empty; } Rectangle itemBounds = _listView.GetItemRect(index, ItemBoundsPortion.Label); Rectangle listviewBounds = _listView.AccessibilityObject.Bounds; Point point = new(listviewBounds.X + itemBounds.X, listviewBounds.Y + itemBounds.Y); return _listView.View switch { View.Details or View.List => GetDetailsListRectangle(point, item, itemBounds), View.Tile => GetTileRectangle(point, item, itemBounds), _ => new Rectangle(point, new Size(itemBounds.Width, itemBounds.Height)), }; } private static Rectangle GetDetailsListRectangle(Point point, ListViewItem item, Rectangle itemBounds) { // The GetItemRect(index, ItemBoundsPortion.Label) method returns the width of the cell, // not the text for "Details" and "List" views. As result, if the text is smaller than the cell, // we return the width of the text. If the text is larger than the cell, we return the width of the cell return new Rectangle( point, new Size(Math.Min(TextRenderer.MeasureText(item.Text, item.Font).Width, itemBounds.Width), itemBounds.Height)); } private Rectangle GetTileRectangle(Point point, ListViewItem item, Rectangle itemBounds) { // The GetItemRect(index, ItemBoundsPortion.Label) method returns the incorrect width of the item for "Tile" view. // When returning the rectangle, we take into account the width of the texts of the item and its sub-item, // because the first sub-item is also displayed in the list int textWidth = TextRenderer.MeasureText(item.Text, item.Font).Width; if (SubItems.Count > 1) { ListViewSubItem subItem = SubItems[1]; textWidth = Math.Max(TextRenderer.MeasureText(subItem.Text, subItem.Font).Width, textWidth); } return new Rectangle(point, new Size(Math.Min(textWidth, itemBounds.Width), itemBounds.Height)); } }