| File: System\Windows\Forms\Design\Behavior\DesignerActionBehavior.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. using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; namespace System.Windows.Forms.Design.Behavior; /// <summary> /// This is the Behavior that represents DesignerActions for a particular control. /// The DesignerActionBehavior is responsible for responding to the MouseDown message and either /// 1) Selecting the control and changing the DesignerActionGlyph's image or /// 2) Building up a chrome menu and requesting it to be shown. /// Also, this Behavior acts as a proxy between "clicked" context menu items and the actual /// DesignerActions that they represent. /// </summary> internal sealed class DesignerActionBehavior : Behavior { private readonly IServiceProvider _serviceProvider; // we need to cache the service provider here to be able to create the panel with the proper arguments private bool _ignoreNextMouseUp; /// <summary> /// Constructor that calls base and caches off the action lists. /// </summary> internal DesignerActionBehavior(IServiceProvider serviceProvider, IComponent relatedComponent, DesignerActionListCollection actionLists, DesignerActionUI parentUI) { ActionLists = actionLists; _serviceProvider = serviceProvider; RelatedComponent = relatedComponent; ParentUI = parentUI; } /// <summary> /// Returns the collection of DesignerActionLists this Behavior is managing. /// These will be dynamically updated (some can be removed, new ones can be added, etc...). /// </summary> internal DesignerActionListCollection ActionLists { get; set; } /// <summary> /// Returns the parenting UI (a DesignerActionUI) /// </summary> internal DesignerActionUI ParentUI { get; } /// <summary> /// Returns the Component that this glyph is attached to. /// </summary> internal IComponent RelatedComponent { get; } /// <summary> /// Hides the designer action panel UI. /// </summary> internal void HideUI() { ParentUI.HideDesignerActionPanel(); } internal DesignerActionPanel CreateDesignerActionPanel(IComponent relatedComponent) { // BUILD AND SHOW THE CHROME UI DesignerActionListCollection lists = new(); lists.AddRange(ActionLists); DesignerActionPanel dap = new(_serviceProvider); dap.UpdateTasks(lists, [], string.Format(SR.DesignerActionPanel_DefaultPanelTitle, relatedComponent.GetType().Name), null); return dap; } /// <summary> /// Shows the designer action panel UI associated with this glyph. /// </summary> internal void ShowUI(Glyph g) { if (g is not DesignerActionGlyph glyph) { Debug.Fail("Why are we trying to 'showui' on a glyph that's not a DesignerActionGlyph?"); return; } DesignerActionPanel dap = CreateDesignerActionPanel(RelatedComponent); ParentUI.ShowDesignerActionPanel(RelatedComponent, dap, glyph); } internal bool IgnoreNextMouseUp { set { _ignoreNextMouseUp = value; } } public override bool OnMouseDoubleClick(Glyph? g, MouseButtons button, Point mouseLoc) { _ignoreNextMouseUp = true; return true; } public override bool OnMouseDown(Glyph? g, MouseButtons button, Point mouseLoc) { // we take the msg return (!ParentUI.IsDesignerActionPanelVisible); } /// <summary> /// In response to a MouseUp, we will either /// 1) select the Glyph and control if not selected, or /// 2) Build up our context menu representing our DesignerActions and show it. /// </summary> public override bool OnMouseUp(Glyph? g, MouseButtons button) { if (button != MouseButtons.Left) { return true; } bool returnValue = true; if (ParentUI.IsDesignerActionPanelVisible) { HideUI(); } else if (!_ignoreNextMouseUp) { if (_serviceProvider.TryGetService(out ISelectionService? selectionService) && selectionService.PrimarySelection != RelatedComponent) { List<IComponent> componentList = [RelatedComponent]; selectionService.SetSelectedComponents(componentList, SelectionTypes.Primary); } if (g is not null) { ShowUI(g); } } else { returnValue = false; } _ignoreNextMouseUp = false; return returnValue; } }