Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / WinForms / System / WinForms / Design / Behavior / ToolboxItemSnapLineBehavior.cs / 1 / ToolboxItemSnapLineBehavior.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.Drawing.Design; using System.Windows.Forms.Design; ////// /// This class implements the behavior provided by DocumentDesigner /// when the user is dragging a valid toolbox item. Here, we'll render a /// default 'box' beneath the cursor that snaps to edges of other /// components on the designer's surface. /// internal class ToolboxItemSnapLineBehavior : Behavior { private IServiceProvider serviceProvider;//used for snaplines private BehaviorService behaviorService;//pointer to our big & bad service private ControlDesigner designer;//used for snaplines as well private bool isPushed;//used to track if this is currently on the stack or not private Graphics graphics;//graphics object for the adornerwindow private Rectangle lastRectangle;//cache the last mouse loc - so we can ignore when mouse doesn't move private Point lastOffset;//cache the last snap so we know where to create our control if dropped private DragAssistanceManager dragManager; //used to apply snaplines when dragging a new tool rect on the designer's surface private bool targetAllowsSnapLines;//indicates if the drop target allows snaplines (flowpanels don't for ex) private StatusCommandUI statusCommandUI; //used to update the StatusBar Information. private bool targetAllowsDragBox; //indicates if the drop target allows the generic drag box to be drawn ////// /// Constructor that caches the designer (which invoked us) and a ptr /// to the BehaviorService. /// public ToolboxItemSnapLineBehavior(IServiceProvider serviceProvider, BehaviorService behaviorService) { this.serviceProvider = serviceProvider; this.behaviorService = behaviorService; this.designer = null; this.isPushed = false; this.lastRectangle= Rectangle.Empty; this.lastOffset = Point.Empty; statusCommandUI = new StatusCommandUI(serviceProvider); this.targetAllowsDragBox = true; targetAllowsSnapLines = true; } public ToolboxItemSnapLineBehavior(IServiceProvider serviceProvider, BehaviorService behaviorService, ControlDesigner controlDesigner) : this(serviceProvider, behaviorService) { this.designer = controlDesigner; //check to see if the current designer participate with SnapLines if (controlDesigner != null && !controlDesigner.ParticipatesWithSnapLines) { targetAllowsSnapLines = false; } } public ToolboxItemSnapLineBehavior(IServiceProvider serviceProvider, BehaviorService behaviorService, ControlDesigner controlDesigner, bool allowDragBox) : this(serviceProvider, behaviorService, controlDesigner) { this.designer = controlDesigner; this.targetAllowsDragBox = allowDragBox; } ////// Demand creates the Graphics object from the AdornerWindow. /// private Graphics Graphics { get { if (graphics == null) { graphics = behaviorService.AdornerWindowGraphics; } return graphics; } } ////// /// OnDragDrop can be overridden so that a Behavior can specify its own /// Drag/Drop rules. /// public bool IsPushed { get { return isPushed; } set { isPushed = value; if (isPushed) { if (dragManager == null) { dragManager = new DragAssistanceManager(serviceProvider); } } else { //clean up all our temp objects if (!lastRectangle.IsEmpty) { behaviorService.Invalidate(lastRectangle); } lastOffset = Point.Empty; lastRectangle = Rectangle.Empty; //destroy the snapline engine (if we used it) if (dragManager != null) { dragManager.OnMouseUp(); dragManager = null; } //dispose graphics if (graphics != null) { graphics.Dispose(); graphics = null; } } } } /// /// Called on a DragDrop - this generates our extra drag info /// to pass along to the base class. Basically, we get the /// last-rendered snaplines before the drop and attempt to //// identify to which direction the mouse was snapped. /// private ToolboxSnapDragDropEventArgs CreateToolboxSnapArgs(DragEventArgs e, Point mouseLoc) { //we're trying to set these two vars here... ToolboxSnapDragDropEventArgs.SnapDirection snapDirections = ToolboxSnapDragDropEventArgs.SnapDirection.None; Point offset = Point.Empty; //as soon as these vars are true - we can stop looking at lines bool horizontalComponentIdentified = false; bool verticalComponentIdentified = false; if (dragManager != null) { DragAssistanceManager.Line[] lines = dragManager.GetRecentLines(); foreach (DragAssistanceManager.Line line in lines) { if (line.LineType == DragAssistanceManager.LineType.Standard) { if (!horizontalComponentIdentified && line.x1 == line.x2) { //check for vertical equality if (line.x1 == lastRectangle.Left) { //we had a line on the left of the box - so we must have snapped left snapDirections |= ToolboxSnapDragDropEventArgs.SnapDirection.Left; offset.X = lastRectangle.Left - mouseLoc.X; } else {//MUST BE RIGHT? if (lines.x1 == lastRectangle.Right) { //we had a line on the right of the box - so we must have snapped right snapDirections |= ToolboxSnapDragDropEventArgs.SnapDirection.Right; offset.X = lastRectangle.Right - mouseLoc.X; } horizontalComponentIdentified = true; } else if (!verticalComponentIdentified && line.y1 == line.y2) { //check for vertical equality if (line.y1 == lastRectangle.Top) { //we had a line on the top of the box - so we must have snapped top snapDirections |= ToolboxSnapDragDropEventArgs.SnapDirection.Top; offset.Y = lastRectangle.Top - mouseLoc.Y; } else if (line.y1 == lastRectangle.Bottom) { //we had a line on the bottom of the box - so we must have snapped bottom snapDirections |= ToolboxSnapDragDropEventArgs.SnapDirection.Bottom; offset.Y = lastRectangle.Bottom - mouseLoc.Y; } verticalComponentIdentified = true; } } else if ((line.LineType == DragAssistanceManager.LineType.Margin) || (line.LineType == DragAssistanceManager.LineType.Padding)) { if (!verticalComponentIdentified && line.x1 == line.x2) { //now, we're looking at a vertical margin line - is it above? if (Math.Max(line.y1, line.y2) <= lastRectangle.Top) { //aha - we had a margin line at the top of the box snapDirections |= ToolboxSnapDragDropEventArgs.SnapDirection.Top; offset.Y = lastRectangle.Top - mouseLoc.Y; } else { //aha - we had a margin line at the bottom of the box snapDirections |= ToolboxSnapDragDropEventArgs.SnapDirection.Bottom; offset.Y = lastRectangle.Bottom - mouseLoc.Y; } verticalComponentIdentified = true; } else if (!horizontalComponentIdentified && line.y1 == line.y2) { //now, we're looking at a horz margin line - is it left? if (Math.Max(line.x1, line.x2) <= lastRectangle.Left) { //aha - we had a margin line at the left of the box snapDirections |= ToolboxSnapDragDropEventArgs.SnapDirection.Left; offset.X = lastRectangle.Left - mouseLoc.X; } else { //aha - we had a margin line at the right of the box snapDirections |= ToolboxSnapDragDropEventArgs.SnapDirection.Right; offset.X = lastRectangle.Right - mouseLoc.X; } horizontalComponentIdentified = true; } } if (horizontalComponentIdentified && verticalComponentIdentified) { //we've found both components - stop looping break; } } } //set default values is we haven't identified any 'snaps' if (!horizontalComponentIdentified) { snapDirections |= ToolboxSnapDragDropEventArgs.SnapDirection.Left; offset.X = lastRectangle.Left - mouseLoc.X; } if (!verticalComponentIdentified) { snapDirections |= ToolboxSnapDragDropEventArgs.SnapDirection.Top; offset.Y = lastRectangle.Top - mouseLoc.Y; } //create our arg and pass it back return new ToolboxSnapDragDropEventArgs(snapDirections, offset, e); } ////// /// Used when dragging a new tool rect on the designer's surface - /// this will return some generic snaplines Allowing the rect to /// snap to existing control edges on the surface. /// private SnapLine[] GenerateNewToolSnapLines(Rectangle r) { return new SnapLine[] {new SnapLine(SnapLineType.Left, r.Left), new SnapLine(SnapLineType.Right, r.Right), new SnapLine(SnapLineType.Bottom, r.Bottom), new SnapLine(SnapLineType.Top, r.Top), new SnapLine(SnapLineType.Horizontal, r.Top -4, SnapLine.MarginTop, SnapLinePriority.Always), new SnapLine(SnapLineType.Horizontal, r.Bottom + 3, SnapLine.MarginBottom, SnapLinePriority.Always), new SnapLine(SnapLineType.Vertical, r.Left -4, SnapLine.MarginLeft, SnapLinePriority.Always), new SnapLine(SnapLineType.Vertical, r.Right + 3, SnapLine.MarginRight, SnapLinePriority.Always)}; } ////// /// OnDragDrop can be overridden so that a Behavior can specify its own /// Drag/Drop rules. /// public override void OnDragDrop(Glyph g, DragEventArgs e) { behaviorService.PopBehavior(this); try { //offset the mouse loc to screen coords for calculations on drops Point screenOffset = behaviorService.AdornerWindowToScreen(); //build up our extra-special event args ToolboxSnapDragDropEventArgs se = CreateToolboxSnapArgs(e, new Point(e.X - screenOffset.X, e.Y - screenOffset.Y)); base.OnDragDrop(g, se); } finally { //clear everything up IsPushed = false; } } // When we begin a drag we need to remove the glyphs that do not allow drops. // VSWhidbey #487816 public void OnBeginDrag() { Adorner bodyAdorner = null; SelectionManager selMgr = (SelectionManager)serviceProvider.GetService(typeof(SelectionManager)); if (selMgr != null) { bodyAdorner = selMgr.BodyGlyphAdorner; } ArrayList glyphsToRemove = new ArrayList(); foreach (ControlBodyGlyph body in bodyAdorner.Glyphs) { Control ctl = body.RelatedComponent as Control; if (ctl != null) { if (!ctl.AllowDrop) { glyphsToRemove.Add(body); } } } foreach (Glyph glyph in glyphsToRemove) { bodyAdorner.Glyphs.Remove(glyph); } } public override bool OnMouseMove(Glyph g, MouseButtons button, Point mouseLoc) { bool altKeyPressed = Control.ModifierKeys == Keys.Alt; if (altKeyPressed && dragManager != null) { //erase any snaplines (if we had any) dragManager.EraseSnapLines(); } //call base bool retValue = base.OnMouseMove(g, button, mouseLoc); //identify where the new box should be... Rectangle newRectangle = new Rectangle(mouseLoc.X- DesignerUtils.BOXIMAGESIZE /2, mouseLoc.Y- DesignerUtils.BOXIMAGESIZE /2, DesignerUtils.BOXIMAGESIZE ,DesignerUtils.BOXIMAGESIZE ); //don't do anything if the loc is the same if (newRectangle != lastRectangle) { if (dragManager != null && targetAllowsSnapLines && !altKeyPressed) { lastOffset = dragManager.OnMouseMove(newRectangle, GenerateNewToolSnapLines(newRectangle)); newRectangle.Offset(lastOffset.X, lastOffset.Y); } //erase old if (!lastRectangle.IsEmpty) { //build up the invalid region Region invalidRegion = new Region(lastRectangle); invalidRegion.Exclude(newRectangle); behaviorService.Invalidate(invalidRegion); } if (targetAllowsDragBox) { Graphics.DrawImage(DesignerUtils.BoxImage, newRectangle.Location); } //offset the mouse loc to screen coords for calculations on drops IDesignerHost host = (IDesignerHost)serviceProvider.GetService(typeof(IDesignerHost)); if (host != null) { Control baseControl = host.RootComponent as Control; if (baseControl != null) { Point adornerServiceOrigin = behaviorService.MapAdornerWindowPoint(baseControl.Handle, new Point(0, 0)); Rectangle statusRect = new Rectangle(newRectangle.X - adornerServiceOrigin.X, newRectangle.Y - adornerServiceOrigin.Y, 0, 0); if (statusCommandUI != null) { statusCommandUI.SetStatusInformation(statusRect); } } } if (dragManager != null && targetAllowsSnapLines && !altKeyPressed) { dragManager.RenderSnapLinesInternal(); } //store this off for the next time around lastRectangle = newRectangle; } return retValue; } } } // 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
- TabControlAutomationPeer.cs
- unsafeIndexingFilterStream.cs
- TiffBitmapDecoder.cs
- XmlSchemaCollection.cs
- ToolStripItem.cs
- ThreadSafeList.cs
- SymmetricAlgorithm.cs
- Binding.cs
- DefaultTraceListener.cs
- VariableQuery.cs
- SlipBehavior.cs
- PseudoWebRequest.cs
- DoubleIndependentAnimationStorage.cs
- DataColumnChangeEvent.cs
- ContentPosition.cs
- XmlWellformedWriter.cs
- ShaderEffect.cs
- X509CertificateValidator.cs
- XsltArgumentList.cs
- OrderByLifter.cs
- SimpleType.cs
- NativeMethods.cs
- Int32CAMarshaler.cs
- HttpChannelBindingToken.cs
- PlatformNotSupportedException.cs
- DbConnectionHelper.cs
- ReflectPropertyDescriptor.cs
- LinkedResourceCollection.cs
- DispatcherSynchronizationContext.cs
- HMACSHA384.cs
- ParameterElementCollection.cs
- SectionVisual.cs
- ApplicationBuildProvider.cs
- Page.cs
- AxDesigner.cs
- NavigatorOutput.cs
- SafeViewOfFileHandle.cs
- WebPartMovingEventArgs.cs
- ActiveXHelper.cs
- PropertyConverter.cs
- ScriptReference.cs
- XmlTextReader.cs
- PageFunction.cs
- DataTableMappingCollection.cs
- ButtonStandardAdapter.cs
- ContractListAdapter.cs
- ColumnResizeUndoUnit.cs
- SerializationInfoEnumerator.cs
- AddingNewEventArgs.cs
- DbSource.cs
- ServiceSettingsResponseInfo.cs
- XmlSubtreeReader.cs
- StyleXamlParser.cs
- IntellisenseTextBox.designer.cs
- XmlSchemaAnnotation.cs
- LinearKeyFrames.cs
- EncoderNLS.cs
- ConfigurationElementProperty.cs
- ConfigurationManagerHelper.cs
- BitmapEffectDrawing.cs
- MultiDataTrigger.cs
- DependencySource.cs
- OdbcErrorCollection.cs
- VisualBasicExpressionConverter.cs
- Configuration.cs
- StreamReader.cs
- RouteUrlExpressionBuilder.cs
- WebPartConnectionsEventArgs.cs
- returneventsaver.cs
- ActivityInstanceMap.cs
- MultiplexingDispatchMessageFormatter.cs
- SolidColorBrush.cs
- GridViewCommandEventArgs.cs
- bidPrivateBase.cs
- ReferenceEqualityComparer.cs
- QilPatternVisitor.cs
- UnmanagedMemoryStream.cs
- ListDictionaryInternal.cs
- Visual3DCollection.cs
- SqlCachedBuffer.cs
- ReflectTypeDescriptionProvider.cs
- EmptyEnumerator.cs
- ScriptControlDescriptor.cs
- HasCopySemanticsAttribute.cs
- BindingExpressionUncommonField.cs
- SoapTypeAttribute.cs
- AppliedDeviceFiltersEditor.cs
- EntityFunctions.cs
- BindingOperations.cs
- Resources.Designer.cs
- LineBreak.cs
- HwndStylusInputProvider.cs
- DataAdapter.cs
- FileLogRecord.cs
- HostedHttpRequestAsyncResult.cs
- IgnoreFileBuildProvider.cs
- AutomationFocusChangedEventArgs.cs
- KeyTimeConverter.cs
- ContractMapping.cs
- BridgeDataReader.cs