| File: System\Windows\Forms\Design\ListViewDesigner.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms.Design\src\System.Windows.Forms.Design.csproj (System.Windows.Forms.Design) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable disable using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; namespace System.Windows.Forms.Design; /// <summary> /// This is the designer for the list view control. It implements hit testing for /// the items in the list view. /// </summary> internal class ListViewDesigner : ControlDesigner { private DesignerActionListCollection _actionLists; private HDHITTESTINFO _hdrhit; private bool _inShowErrorDialog; /// <summary> /// Retrieves a list of associated components. These are components that should be included /// in a cut or copy operation on this component. /// </summary> public override ICollection AssociatedComponents { get { ListView lv = Control as ListView; if (lv is not null) { return lv.Columns; } return base.AssociatedComponents; } } private bool OwnerDraw { get { return (bool)ShadowProperties[nameof(OwnerDraw)]; } set { ShadowProperties[nameof(OwnerDraw)] = value; } } private View View { get { return ((ListView)Component).View; } set { ((ListView)Component).View = value; if (value == View.Details) { HookChildHandles((HWND)Control.Handle); } } } protected override unsafe bool GetHitTest(Point point) { // We override GetHitTest to make the header in report view UI-active. ListView listView = (ListView)Component; if (listView.View == View.Details) { Point listViewPoint = Control.PointToClient(point); HWND hwndHit = PInvoke.ChildWindowFromPointEx(listView, listViewPoint, CWP_FLAGS.CWP_SKIPINVISIBLE); if (!hwndHit.IsNull && hwndHit != listView.Handle) { HWND headerHwnd = (HWND)PInvokeCore.SendMessage(listView, PInvoke.LVM_GETHEADER); if (hwndHit == headerHwnd) { PInvokeCore.MapWindowPoints(HWND.Null, headerHwnd, ref point); _hdrhit.pt = point; PInvokeCore.SendMessage(headerHwnd, PInvoke.HDM_HITTEST, 0, ref _hdrhit); if (_hdrhit.flags == HEADER_HITTEST_INFO_FLAGS.HHT_ONDIVIDER) return true; } } } return false; } public override void Initialize(IComponent component) { ListView lv = (ListView)component; OwnerDraw = lv.OwnerDraw; lv.OwnerDraw = false; lv.UseCompatibleStateImageBehavior = false; AutoResizeHandles = true; base.Initialize(component); if (lv.View == View.Details) { HookChildHandles((HWND)Control.Handle); } } protected override void PreFilterProperties(IDictionary properties) { PropertyDescriptor ownerDrawProp = (PropertyDescriptor)properties["OwnerDraw"]; if (ownerDrawProp is not null) { properties["OwnerDraw"] = TypeDescriptor.CreateProperty(typeof(ListViewDesigner), ownerDrawProp, []); } PropertyDescriptor viewProp = (PropertyDescriptor)properties["View"]; if (viewProp is not null) { properties["View"] = TypeDescriptor.CreateProperty(typeof(ListViewDesigner), viewProp, []); } base.PreFilterProperties(properties); } protected override unsafe void WndProc(ref Message m) { switch (m.Msg) { case (int)PInvokeCore.WM_NOTIFY: case (int)MessageId.WM_REFLECT_NOTIFY: NMHDR* nmhdr = (NMHDR*)(nint)m.LParamInternal; if (nmhdr->code == PInvoke.HDN_ENDTRACKW) { // Re-codegen if the columns have been resized try { GetService<IComponentChangeService>().OnComponentChanged(Component); } catch (InvalidOperationException ex) { if (_inShowErrorDialog) { return; } _inShowErrorDialog = true; try { ShowErrorDialog(Component.Site.GetService<IUIService>(), ex, (ListView)Component); } finally { _inShowErrorDialog = false; } return; } } break; } base.WndProc(ref m); } public override DesignerActionListCollection ActionLists { get { if (_actionLists is null) { _actionLists = new DesignerActionListCollection(); _actionLists.Add(new ListViewActionList(this)); } return _actionLists; } } private static void ShowErrorDialog(IUIService uiService, InvalidOperationException ex, Control control) { if (uiService is not null) { uiService.ShowError(ex); } else { string message = ex.Message; if (message is null || message.Length == 0) { message = ex.ToString(); } RTLAwareMessageBox.Show(control, message, null, MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1, 0); } } }