Code:
/ FX-1434 / FX-1434 / 1.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
- XmlAttributeAttribute.cs
- ToolboxBitmapAttribute.cs
- WebPartsPersonalizationAuthorization.cs
- TreeView.cs
- ToolStripDropDownItem.cs
- DataGridViewUtilities.cs
- ListContractAdapter.cs
- PackageFilter.cs
- ArgumentValidation.cs
- WebPartEditorCancelVerb.cs
- DataPointer.cs
- CheckBox.cs
- ItemCheckedEvent.cs
- CompiledWorkflowDefinitionContext.cs
- RuntimeEnvironment.cs
- Pair.cs
- SignatureDescription.cs
- SecurityKeyIdentifier.cs
- ResourcePool.cs
- CodeGroup.cs
- ArrayExtension.cs
- DbFunctionCommandTree.cs
- FloatUtil.cs
- PrinterUnitConvert.cs
- FileChangeNotifier.cs
- Keyboard.cs
- PublisherIdentityPermission.cs
- UmAlQuraCalendar.cs
- BindingExpressionBase.cs
- TokenBasedSetEnumerator.cs
- AccessViolationException.cs
- Array.cs
- ErrorProvider.cs
- LambdaExpression.cs
- DefaultHttpHandler.cs
- ClassHandlersStore.cs
- ThreadInterruptedException.cs
- NavigationService.cs
- ComplexTypeEmitter.cs
- StringInfo.cs
- VirtualPath.cs
- DbProviderSpecificTypePropertyAttribute.cs
- BatchWriter.cs
- MatrixCamera.cs
- AffineTransform3D.cs
- ScalarConstant.cs
- HtmlControlPersistable.cs
- InputReferenceExpression.cs
- TextEndOfSegment.cs
- Geometry3D.cs
- WorkflowRuntimeServiceElementCollection.cs
- ConnectivityStatus.cs
- CodeGenerator.cs
- wgx_exports.cs
- CompilerError.cs
- Message.cs
- ToolboxItemAttribute.cs
- TraceLog.cs
- RectangleConverter.cs
- SqlError.cs
- StructuralType.cs
- TableCell.cs
- ErrorStyle.cs
- InvalidOperationException.cs
- DesignTimeDataBinding.cs
- SafeEventHandle.cs
- GregorianCalendarHelper.cs
- TimeEnumHelper.cs
- MethodBody.cs
- ChannelManager.cs
- GenericTypeParameterBuilder.cs
- DocumentCollection.cs
- DataGridColumn.cs
- XNameTypeConverter.cs
- DataGridPageChangedEventArgs.cs
- SqlClientPermission.cs
- LocalizableAttribute.cs
- MarshalByRefObject.cs
- Int32Storage.cs
- EventRecord.cs
- MouseButton.cs
- PresentationAppDomainManager.cs
- ThreadStateException.cs
- ReadOnlyCollection.cs
- DropSource.cs
- TraceProvider.cs
- TextSchema.cs
- FilteredSchemaElementLookUpTable.cs
- ManagementObjectSearcher.cs
- ClrProviderManifest.cs
- ContextMarshalException.cs
- TypeLoadException.cs
- ConfigurationException.cs
- DynamicDataResources.Designer.cs
- DebugHandleTracker.cs
- wgx_render.cs
- RelationalExpressions.cs
- controlskin.cs
- SortedList.cs
- ECDiffieHellmanCng.cs