Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / WinForms / System / WinForms / Design / Behavior / ContainerSelectorBehavior.cs / 1 / ContainerSelectorBehavior.cs
namespace System.Windows.Forms.Design.Behavior { using System; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Design; using System.Diagnostics; using System.Drawing; using System.Windows.Forms.Design; ////// /// This behavior is associated with the ContainerGlyph offered up /// by ParentControlDesigner. This Behavior simply /// starts a new dragdrop behavior. /// internal sealed class ContainerSelectorBehavior : Behavior { private Control containerControl; //our related control private IServiceProvider serviceProvider; //used for starting a drag/drop private BehaviorService behaviorService; //ptr to where we start our drag/drop operation private bool okToMove; //state identifying if we are allowed to move the container private Point initialDragPoint; //cached "mouse down" point // For VSWhidbey 464206. For some controls, we want to change the original drag point to be the upper-left of the control in // order to make it easier to drop the control at a desired location. But not all controls want this behavior. E.g. we want // to do it for Panel and ToolStrip, but not for Label. Label has a ContainerSelectorBehavior via the NoResizeSelectionBorder // glyph. private bool setInitialDragPoint; ////// /// Constructor, here we cache off all of our member vars and sync /// location & size changes. /// internal ContainerSelectorBehavior(Control containerControl, IServiceProvider serviceProvider) { Init(containerControl, serviceProvider); this.setInitialDragPoint = false; } ////// /// Constructor, here we cache off all of our member vars and sync /// location & size changes. /// internal ContainerSelectorBehavior(Control containerControl, IServiceProvider serviceProvider, bool setInitialDragPoint) { Init(containerControl, serviceProvider); this.setInitialDragPoint = setInitialDragPoint; } private void Init(Control containerControl, IServiceProvider serviceProvider) { this.behaviorService = (BehaviorService)serviceProvider.GetService(typeof(BehaviorService)); if (behaviorService == null) { Debug.Fail("Could not get the BehaviorService from ContainerSelectroBehavior!"); return; } this.containerControl = containerControl; this.serviceProvider = serviceProvider; this.initialDragPoint = Point.Empty; this.okToMove = false; } public Control ContainerControl { get { return containerControl; } } ////// /// This will be true when we detect a mousedown on our glyph. The Glyph can use this state /// to always return 'true' from hittesting indicating that it would like all messages (like mousemove). /// public bool OkToMove { get { return okToMove; } set { okToMove = value; } } public Point InitialDragPoint { get { return initialDragPoint; } set { initialDragPoint = value; } } ////// /// If the user selects the containerglyph - select our related component. /// public override bool OnMouseDown(Glyph g, MouseButtons button, Point mouseLoc) { if (button == MouseButtons.Left) { //select our component ISelectionService selSvc = (ISelectionService)serviceProvider.GetService(typeof(ISelectionService)); if (selSvc != null && !containerControl.Equals(selSvc.PrimarySelection as Control)) { selSvc.SetSelectedComponents(new object[] {containerControl}, SelectionTypes.Primary | SelectionTypes.Toggle); // VSWhidbey #488545 // Setting the selected component will create a new glyph, so this instance of the glyph won't // receive any more mouse messages. So we need to tell the new glyph what the initialDragPoint and okToMove are. // Sigh.... Here we go. ContainerSelectorGlyph selOld = g as ContainerSelectorGlyph; if (selOld == null) { return false; } foreach (Adorner a in behaviorService.Adorners) { foreach (Glyph glyph in a.Glyphs) { ContainerSelectorGlyph selNew = glyph as ContainerSelectorGlyph; if (selNew == null) { continue; } // Don't care if we are looking at the same containerselectorglyph if (selNew.Equals(selOld)) { continue; } // Check if the containercontrols are the same ContainerSelectorBehavior behNew = selNew.RelatedBehavior as ContainerSelectorBehavior; ContainerSelectorBehavior behOld = selOld.RelatedBehavior as ContainerSelectorBehavior; if (behNew == null || behOld == null) { continue; } // and the relatedcomponents are the same, then we have found the new glyph that just got added if (behOld.ContainerControl.Equals(behNew.ContainerControl)) { behNew.OkToMove = true; behNew.InitialDragPoint = DetermineInitialDragPoint(mouseLoc); break; } } } } else { InitialDragPoint = DetermineInitialDragPoint(mouseLoc); //set 'okToMove' to true since the user actually clicked down on the glyph OkToMove = true; } } return false; } private Point DetermineInitialDragPoint(Point mouseLoc) { if (setInitialDragPoint) { // Set the mouse location to be to control's location. Point controlOrigin = behaviorService.ControlToAdornerWindow(containerControl); controlOrigin = behaviorService.AdornerWindowPointToScreen(controlOrigin); Cursor.Position = controlOrigin; return controlOrigin; } else { // This really amounts to doing nothing return mouseLoc; } } ////// /// We will compare the mouse loc to the initial point (set in onmousedown) /// and if we're far enough, we'll create a dropsourcebehavior object and start /// out drag operation! /// public override bool OnMouseMove(Glyph g, MouseButtons button, Point mouseLoc) { if (button == MouseButtons.Left && OkToMove) { if (InitialDragPoint == Point.Empty) { InitialDragPoint = DetermineInitialDragPoint(mouseLoc); } Size delta = new Size(Math.Abs(mouseLoc.X - InitialDragPoint.X), Math.Abs(mouseLoc.Y - InitialDragPoint.Y)); if (delta.Width >= DesignerUtils.MinDragSize.Width/2 || delta.Height >= DesignerUtils.MinDragSize.Height/2) { //start our drag! Point screenLoc = behaviorService.AdornerWindowToScreen(); screenLoc.Offset(mouseLoc.X, mouseLoc.Y); StartDragOperation(screenLoc); } } return false; } ////// /// Simply clear the initial drag point, so we can start again /// on the next mouse down. /// public override bool OnMouseUp(Glyph g, MouseButtons button) { InitialDragPoint = Point.Empty; OkToMove = false; return false; } ////// Called when we've identified that we want to start a drag operation /// with our data container. /// private void StartDragOperation(Point initialMouseLocation) { //need to grab a hold of some services ISelectionService selSvc = (ISelectionService)serviceProvider.GetService(typeof(ISelectionService)); IDesignerHost host = (IDesignerHost)serviceProvider.GetService(typeof(IDesignerHost)); if (selSvc == null || host == null) { Debug.Fail("Can't drag this Container! Either SelectionService is null or DesignerHost is null"); return; } //must identify a required parent to avoid dragging mixes of children Control requiredParent = containerControl.Parent; ArrayList dragControls = new ArrayList(); ICollection selComps = selSvc.GetSelectedComponents(); //create our list of controls-to-drag foreach (IComponent comp in selComps) { Control ctrl = comp as Control; if (ctrl != null) { if (!ctrl.Parent.Equals(requiredParent)) { continue;//mixed selection of different parents - don't add this } ControlDesigner des = host.GetDesigner(ctrl) as ControlDesigner; if (des != null && (des.SelectionRules & SelectionRules.Moveable) != 0) { dragControls.Add(ctrl); } } } //if we have controls-to-drag, create our new behavior and start the drag/drop operation if (dragControls.Count > 0) { Point controlOrigin; if (setInitialDragPoint) { // In this case we want the initialmouselocation to be the control's origin. controlOrigin = behaviorService.ControlToAdornerWindow(containerControl); controlOrigin = behaviorService.AdornerWindowPointToScreen(controlOrigin); } else { controlOrigin = initialMouseLocation; } DropSourceBehavior dsb = new DropSourceBehavior(dragControls, containerControl.Parent, controlOrigin); try { behaviorService.DoDragDrop(dsb); } finally { OkToMove = false; InitialDragPoint = Point.Empty; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BaseInfoTable.cs
- RegistryPermission.cs
- InputDevice.cs
- AutomationPropertyInfo.cs
- Clipboard.cs
- IndexedGlyphRun.cs
- IUnknownConstantAttribute.cs
- IsolatedStorageFilePermission.cs
- IPPacketInformation.cs
- IsolatedStorageFilePermission.cs
- Table.cs
- StyleModeStack.cs
- BrowserCapabilitiesFactoryBase.cs
- RadioButtonPopupAdapter.cs
- DependencySource.cs
- PermissionListSet.cs
- embossbitmapeffect.cs
- ToolStripRenderer.cs
- SmiContext.cs
- OSFeature.cs
- CodeTypeReference.cs
- FrameworkPropertyMetadata.cs
- Root.cs
- SettingsSavedEventArgs.cs
- DrawTreeNodeEventArgs.cs
- EntityDataSourceWrapperPropertyDescriptor.cs
- ThaiBuddhistCalendar.cs
- XmlNodeComparer.cs
- OdbcUtils.cs
- SourceInterpreter.cs
- WsatConfiguration.cs
- ZipIOExtraFieldElement.cs
- CrossAppDomainChannel.cs
- FormsIdentity.cs
- filewebrequest.cs
- ProcessInfo.cs
- UserControlDesigner.cs
- ArrayElementGridEntry.cs
- EdmEntityTypeAttribute.cs
- ObjectStateEntryDbDataRecord.cs
- EdgeProfileValidation.cs
- CacheHelper.cs
- SmtpNtlmAuthenticationModule.cs
- BufferAllocator.cs
- UIElementParaClient.cs
- ColumnCollection.cs
- PersonalizationStateInfoCollection.cs
- ContainerCodeDomSerializer.cs
- MembershipValidatePasswordEventArgs.cs
- listitem.cs
- LinqDataSourceEditData.cs
- DispatcherTimer.cs
- VectorAnimation.cs
- CompositeClientFormatter.cs
- ToolStripSettings.cs
- TypedServiceOperationListItem.cs
- SendMailErrorEventArgs.cs
- HtmlControl.cs
- LookupBindingPropertiesAttribute.cs
- MsmqIntegrationBindingElement.cs
- HandleCollector.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- TabControlEvent.cs
- TargetInvocationException.cs
- PartialCachingAttribute.cs
- SoapSchemaImporter.cs
- SecurityPolicySection.cs
- ConnectionStringsSection.cs
- printdlgexmarshaler.cs
- MimeTypeMapper.cs
- DependencyPropertyAttribute.cs
- CompilerErrorCollection.cs
- WebPartActionVerb.cs
- contentDescriptor.cs
- CaseStatementSlot.cs
- SerializationInfoEnumerator.cs
- RuntimeHelpers.cs
- ObjectDataSourceDisposingEventArgs.cs
- ArrayWithOffset.cs
- MobileTemplatedControlDesigner.cs
- Menu.cs
- BitmapImage.cs
- Rfc4050KeyFormatter.cs
- DataGridColumnCollection.cs
- prompt.cs
- MetadataCollection.cs
- FontNameConverter.cs
- AttachedAnnotationChangedEventArgs.cs
- ObjectHandle.cs
- ImplicitInputBrush.cs
- UrlPropertyAttribute.cs
- EventDescriptor.cs
- AuthenticationSection.cs
- XmlUtil.cs
- CommonProperties.cs
- While.cs
- AttributeProviderAttribute.cs
- ProjectedWrapper.cs
- SliderAutomationPeer.cs
- EventProviderWriter.cs