diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/Behavior/BehaviorService.AdornerWindow.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/Behavior/BehaviorService.AdornerWindow.cs index 96641808421..f81b13ac56f 100644 --- a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/Behavior/BehaviorService.AdornerWindow.cs +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/Behavior/BehaviorService.AdornerWindow.cs @@ -22,7 +22,7 @@ private partial class AdornerWindow : Control /// Constructor that parents itself to the Designer Frame and hooks all /// necessary events. /// - internal AdornerWindow(BehaviorService behaviorService, Control designerFrame) + internal AdornerWindow(BehaviorService behaviorService, DesignerFrame designerFrame) { _behaviorService = behaviorService; DesignerFrame = designerFrame; @@ -89,13 +89,13 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - internal Control DesignerFrame { get; private set; } + internal DesignerFrame DesignerFrame { get; private set; } /// /// Returns the display rectangle for the adorner window /// internal Rectangle DesignerFrameDisplayRectangle - => DesignerFrameValid ? ((DesignerFrame)DesignerFrame).DisplayRectangle : Rectangle.Empty; + => DesignerFrameValid ? DesignerFrame.DisplayRectangle : Rectangle.Empty; /// /// Returns true if the DesignerFrame is created and not being disposed. @@ -130,7 +130,7 @@ internal void InvalidateAdornerWindow(Region region) if (DesignerFrameValid) { // Translate for non-zero scroll positions - Point scrollPosition = ((DesignerFrame)DesignerFrame).AutoScrollPosition; + Point scrollPosition = DesignerFrame.AutoScrollPosition; region.Translate(scrollPosition.X, scrollPosition.Y); DesignerFrame.Invalidate(region, true); @@ -147,7 +147,7 @@ internal void InvalidateAdornerWindow(Rectangle rectangle) if (DesignerFrameValid) { // Translate for non-zero scroll positions - Point scrollPosition = ((DesignerFrame)DesignerFrame).AutoScrollPosition; + Point scrollPosition = DesignerFrame.AutoScrollPosition; rectangle.Offset(scrollPosition.X, scrollPosition.Y); DesignerFrame.Invalidate(rectangle, true); diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/Behavior/BehaviorService.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/Behavior/BehaviorService.cs index a3265e88e43..e3112a61707 100644 --- a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/Behavior/BehaviorService.cs +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/Behavior/BehaviorService.cs @@ -54,7 +54,7 @@ private static readonly TraceSwitch s_dragDropSwitch private static MessageId WM_GETRECENTSNAPLINES; private const string ToolboxFormat = ".NET Toolbox Item"; // used to detect if a drag is coming from the toolbox. - internal BehaviorService(IServiceProvider serviceProvider, Control windowFrame) + internal BehaviorService(IServiceProvider serviceProvider, DesignerFrame windowFrame) { _serviceProvider = serviceProvider; _adornerWindow = new AdornerWindow(this, windowFrame); diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DesignerFrame.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DesignerFrame.cs index da16101c22f..697944eb00e 100644 --- a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DesignerFrame.cs +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DesignerFrame.cs @@ -1,14 +1,11 @@ // 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; using System.Windows.Forms.Design.Behavior; -using Microsoft.Win32; namespace System.Windows.Forms.Design; @@ -29,10 +26,10 @@ internal class DesignerFrame : Control, IOverlayService, ISplitWindowService, IC { private readonly ISite _designerSite; private readonly OverlayControl _designerRegion; - private Splitter _splitter; - private Control _designer; - private BehaviorService _behaviorService; - private readonly IUIService _uiService; + private Splitter? _splitter; + private Control? _designer; + private BehaviorService? _behaviorService; + private readonly IUIService? _uiService; /// /// Initializes a new instance of the class. @@ -42,13 +39,10 @@ public DesignerFrame(ISite site) Text = "DesignerFrame"; _designerSite = site; _designerRegion = new OverlayControl(site); - _uiService = _designerSite.GetService(typeof(IUIService)) as IUIService; - if (_uiService is not null) + _uiService = _designerSite.GetService(); + if (_uiService?.Styles["ArtboardBackground"] is Color color) { - if (_uiService.Styles["ArtboardBackground"] is Color) - { - BackColor = (Color)_uiService.Styles["ArtboardBackground"]; - } + BackColor = color; } Controls.Add(_designerRegion); @@ -61,23 +55,12 @@ public DesignerFrame(ISite site) /// Returns the scroll offset for the scrollable control that manages all overlays. This is needed by the /// BehaviorService so we can correctly invalidate our AdornerWindow based on scrollposition. /// - internal Point AutoScrollPosition - { - get => _designerRegion.AutoScrollPosition; - } + internal Point AutoScrollPosition => _designerRegion.AutoScrollPosition; /// /// Demand creates a ptr to the BehaviorService - we do this so we can route keyboard message to it. /// - private BehaviorService BehaviorService - { - get - { - _behaviorService ??= _designerSite.GetService(typeof(BehaviorService)) as BehaviorService; - - return _behaviorService; - } - } + private BehaviorService? BehaviorService => _behaviorService ??= _designerSite.GetService(); protected override void Dispose(bool disposing) { @@ -132,17 +115,14 @@ public void Initialize(Control view) protected override void OnGotFocus(EventArgs e) { ForceDesignerRedraw(true); - ISelectionService selSvc = (ISelectionService)_designerSite.GetService(typeof(ISelectionService)); - if (selSvc is not null) + ISelectionService? selSvc = _designerSite.GetService(); + if (selSvc?.PrimarySelection is Control { IsDisposed: false } ctrl) { - if (selSvc.PrimarySelection is Control ctrl && !ctrl.IsDisposed) - { - PInvoke.NotifyWinEvent( - (uint)AccessibleEvents.Focus, - ctrl, - (int)OBJECT_IDENTIFIER.OBJID_CLIENT, - (int)PInvoke.CHILDID_SELF); - } + PInvoke.NotifyWinEvent( + (uint)AccessibleEvents.Focus, + ctrl, + (int)OBJECT_IDENTIFIER.OBJID_CLIENT, + (int)PInvoke.CHILDID_SELF); } } @@ -154,10 +134,10 @@ protected override void OnLostFocus(EventArgs e) ForceDesignerRedraw(false); } - private void OnSplitterMoved(object sender, SplitterEventArgs e) + private void OnSplitterMoved(object? sender, SplitterEventArgs e) { // Dirty the designer. - if (_designerSite.TryGetService(out IComponentChangeService changeService)) + if (_designerSite.TryGetService(out IComponentChangeService? changeService)) { try { @@ -170,14 +150,6 @@ private void OnSplitterMoved(object sender, SplitterEventArgs e) } } - private void OnUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) - { - if (e.Category == UserPreferenceCategory.Window && _designer is not null) - { - SyncDesignerUI(); - } - } - /// /// We override this to do nothing. Otherwise, all the nice keyboard messages we want would get run through the Form's keyboard handling procedure. /// @@ -190,7 +162,7 @@ private void SyncDesignerUI() { Size selectionSize = DesignerUtils.GetAdornmentDimensions(AdornmentType.Maximum); _designerRegion.AutoScrollMargin = selectionSize; - _designer.Location = new Point(selectionSize.Width, selectionSize.Height); + _designer!.Location = new Point(selectionSize.Width, selectionSize.Height); BehaviorService?.SyncSelection(); } @@ -215,46 +187,21 @@ protected override void WndProc(ref Message m) break; // Provide keyboard access for scrolling case PInvoke.WM_KEYDOWN: - SCROLLBAR_COMMAND wScrollNotify = 0; - MessageId msg = PInvoke.WM_NULL; Keys keycode = (Keys)(m.WParamInternal & 0xFFFF); - switch (keycode) + (SCROLLBAR_COMMAND wScrollNotify, MessageId msg) = keycode switch { - case Keys.Up: - wScrollNotify = SCROLLBAR_COMMAND.SB_LINEUP; - msg = PInvoke.WM_VSCROLL; - break; - case Keys.Down: - wScrollNotify = SCROLLBAR_COMMAND.SB_LINEDOWN; - msg = PInvoke.WM_VSCROLL; - break; - case Keys.PageUp: - wScrollNotify = SCROLLBAR_COMMAND.SB_PAGEUP; - msg = PInvoke.WM_VSCROLL; - break; - case Keys.PageDown: - wScrollNotify = SCROLLBAR_COMMAND.SB_PAGEDOWN; - msg = PInvoke.WM_VSCROLL; - break; - case Keys.Home: - wScrollNotify = SCROLLBAR_COMMAND.SB_TOP; - msg = PInvoke.WM_VSCROLL; - break; - case Keys.End: - wScrollNotify = SCROLLBAR_COMMAND.SB_BOTTOM; - msg = PInvoke.WM_VSCROLL; - break; - case Keys.Left: - wScrollNotify = SCROLLBAR_COMMAND.SB_LINEUP; - msg = PInvoke.WM_HSCROLL; - break; - case Keys.Right: - wScrollNotify = SCROLLBAR_COMMAND.SB_LINEDOWN; - msg = PInvoke.WM_HSCROLL; - break; - } - - if ((msg == PInvoke.WM_VSCROLL) || (msg == PInvoke.WM_HSCROLL)) + Keys.Up => (SCROLLBAR_COMMAND.SB_LINEUP, (MessageId)PInvoke.WM_VSCROLL), + Keys.Down => (SCROLLBAR_COMMAND.SB_LINEDOWN, (MessageId)PInvoke.WM_VSCROLL), + Keys.PageUp => (SCROLLBAR_COMMAND.SB_PAGEUP, (MessageId)PInvoke.WM_VSCROLL), + Keys.PageDown => (SCROLLBAR_COMMAND.SB_PAGEDOWN, (MessageId)PInvoke.WM_VSCROLL), + Keys.Home => (SCROLLBAR_COMMAND.SB_TOP, (MessageId)PInvoke.WM_VSCROLL), + Keys.End => (SCROLLBAR_COMMAND.SB_BOTTOM, (MessageId)PInvoke.WM_VSCROLL), + Keys.Left => (SCROLLBAR_COMMAND.SB_LINEUP, (MessageId)PInvoke.WM_HSCROLL), + Keys.Right => (SCROLLBAR_COMMAND.SB_LINEDOWN, (MessageId)PInvoke.WM_HSCROLL), + _ => ((SCROLLBAR_COMMAND)0, (MessageId)PInvoke.WM_NULL) + }; + + if (msg == PInvoke.WM_VSCROLL || msg == PInvoke.WM_HSCROLL) { // Send a message to ourselves to scroll PInvoke.SendMessage(_designerRegion, msg, (WPARAM)(int)wScrollNotify); @@ -263,7 +210,7 @@ protected override void WndProc(ref Message m) break; case PInvoke.WM_CONTEXTMENU: - PInvoke.SendMessage(_designer, m.MsgInternal, m.WParamInternal, m.LParamInternal); + PInvoke.SendMessage(_designer!, m.MsgInternal, m.WParamInternal, m.LParamInternal); return; } @@ -317,9 +264,9 @@ void ISplitWindowService.AddSplitWindow(Control window) if (_splitter is null) { _splitter = new Splitter(); - if (_uiService is not null && _uiService.Styles["HorizontalResizeGrip"] is Color) + if (_uiService?.Styles["HorizontalResizeGrip"] is Color color) { - _splitter.BackColor = (Color)_uiService.Styles["HorizontalResizeGrip"]; + _splitter.BackColor = color; } else { @@ -366,7 +313,7 @@ void ISplitWindowService.RemoveSplitWindow(Control window) /// IEnumerable IContainsThemedScrollbarWindows.ThemedScrollbarWindows() { - ArrayList windows = new ArrayList(); + List windows = new(Controls.Count); foreach (Control c in Controls) { ThemedScrollbarWindow windowInfo = new ThemedScrollbarWindow { Handle = c.Handle }; @@ -390,10 +337,10 @@ IEnumerable IContainsThemedScrollbarWindows.ThemedScrollbarWindows() /// private class OverlayControl : ScrollableControl { - private readonly ArrayList _overlayList; + private readonly List _overlayList; private readonly IServiceProvider _provider; internal bool _messageMouseWheelProcessed; - private BehaviorService _behaviorService; + private BehaviorService? _behaviorService; /// /// Creates a new overlay control. @@ -401,7 +348,7 @@ private class OverlayControl : ScrollableControl public OverlayControl(IServiceProvider provider) { _provider = provider; - _overlayList = new ArrayList(); + _overlayList = new List(); AutoScroll = true; Text = "OverlayControl"; } @@ -414,15 +361,7 @@ protected override AccessibleObject CreateAccessibilityInstance() /// /// Demand creates a ptr to the BehaviorService /// - private BehaviorService BehaviorService - { - get - { - _behaviorService ??= _provider.GetService(typeof(BehaviorService)) as BehaviorService; - - return _behaviorService; - } - } + private BehaviorService? BehaviorService => _behaviorService ??= _provider.GetService(); /// /// At handle creation time we request the designer's handle and parent it. @@ -431,12 +370,9 @@ protected override void OnCreateControl() { base.OnCreateControl(); // Loop through all of the overlays, create them, and hook them up - if (_overlayList is not null) + foreach (Control c in _overlayList) { - foreach (Control c in _overlayList) - { - ParentOverlay(c); - } + ParentOverlay(c); } // We've reparented everything, which means that our selection UI is probably out of sync. Ask it to sync. @@ -453,12 +389,9 @@ protected override void OnLayout(LayoutEventArgs e) // Loop through all of the overlays and size them. Also make sure that they are still on top of the // zorder, because a handle recreate could have changed this. - if (_overlayList is not null) + foreach (Control c in _overlayList) { - foreach (Control c in _overlayList) - { - c.Bounds = client; - } + c.Bounds = client; } } @@ -512,7 +445,7 @@ public void RemoveOverlay(Control control) public void InsertOverlay(Control control, int index) { Debug.Assert(_overlayList.IndexOf(control) == -1, $"Duplicate overlay in overlay service: {control.GetType().FullName}"); - Control c = (Control)_overlayList[index]; + Control c = _overlayList[index]; RemoveOverlay(c); PushOverlay(control); PushOverlay(c); @@ -527,13 +460,11 @@ public void InvalidateOverlays(Rectangle screenRectangle) // paint in inverse order so that things at the front paint last. for (int i = _overlayList.Count - 1; i >= 0; i--) { - if (_overlayList[i] is Control overlayControl) + Control overlayControl = _overlayList[i]; + Rectangle invalidateRect = new Rectangle(overlayControl.PointToClient(screenRectangle.Location), screenRectangle.Size); + if (overlayControl.ClientRectangle.IntersectsWith(invalidateRect)) { - Rectangle invalidateRect = new Rectangle(overlayControl.PointToClient(screenRectangle.Location), screenRectangle.Size); - if (overlayControl.ClientRectangle.IntersectsWith(invalidateRect)) - { - overlayControl.Invalidate(invalidateRect); - } + overlayControl.Invalidate(invalidateRect); } } } @@ -546,17 +477,15 @@ public void InvalidateOverlays(Region screenRegion) // paint in inverse order so that things at the front paint last. for (int i = _overlayList.Count - 1; i >= 0; i--) { - if (_overlayList[i] is Control overlayControl) - { - Rectangle overlayControlScreenBounds = overlayControl.Bounds; - overlayControlScreenBounds.Location = overlayControl.PointToScreen(overlayControl.Location); - using Region intersectionRegion = screenRegion.Clone(); - // get the intersection of everything on the screen that's invalidating and the overlaycontrol - intersectionRegion.Intersect(overlayControlScreenBounds); - // translate this down to overlay control coordinates. - intersectionRegion.Translate(-overlayControlScreenBounds.X, -overlayControlScreenBounds.Y); - overlayControl.Invalidate(intersectionRegion); - } + Control overlayControl = _overlayList[i]; + Rectangle overlayControlScreenBounds = overlayControl.Bounds; + overlayControlScreenBounds.Location = overlayControl.PointToScreen(overlayControl.Location); + using Region intersectionRegion = screenRegion.Clone(); + // get the intersection of everything on the screen that's invalidating and the overlaycontrol + intersectionRegion.Intersect(overlayControlScreenBounds); + // translate this down to overlay control coordinates. + intersectionRegion.Translate(-overlayControlScreenBounds.X, -overlayControlScreenBounds.Y); + overlayControl.Invalidate(intersectionRegion); } } @@ -568,32 +497,29 @@ protected override void WndProc(ref Message m) base.WndProc(ref m); if (m.MsgInternal == PInvoke.WM_PARENTNOTIFY && m.WParamInternal.LOWORD == PInvoke.WM_CREATE) { - if (_overlayList is not null) + bool ourWindow = false; + foreach (Control c in _overlayList) { - bool ourWindow = false; - foreach (Control c in _overlayList) + if (c.IsHandleCreated && m.LParamInternal == c.Handle) { - if (c.IsHandleCreated && m.LParamInternal == c.Handle) - { - ourWindow = true; - break; - } + ourWindow = true; + break; } + } - if (!ourWindow) + if (!ourWindow) + { + foreach (Control c in _overlayList) { - foreach (Control c in _overlayList) - { - PInvoke.SetWindowPos( - c, - HWND.HWND_TOP, - 0, 0, 0, 0, - SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOMOVE); - } + PInvoke.SetWindowPos( + c, + HWND.HWND_TOP, + 0, 0, 0, 0, + SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOMOVE); } } } - else if ((m.Msg == (int)PInvoke.WM_VSCROLL || m.Msg == (int)PInvoke.WM_HSCROLL) && BehaviorService is not null) + else if (m.Msg is (int)PInvoke.WM_VSCROLL or (int)PInvoke.WM_HSCROLL && BehaviorService is not null) { BehaviorService.SyncSelection(); } @@ -610,13 +536,13 @@ public OverlayControlAccessibleObject(OverlayControl owner) : base(owner) { } - public override AccessibleObject HitTest(int x, int y) + public override AccessibleObject? HitTest(int x, int y) { // Since the SelectionUIOverlay in first in the z-order, it normally gets // returned from accHitTest. But we'd rather expose the form that is being // designed. // - foreach (Control c in Owner.Controls) + foreach (Control c in Owner!.Controls) { AccessibleObject cao = c.AccessibilityObject; if (cao.Bounds.Contains(x, y))