GoControl is not Snaping into grid cell

Hello there,

I have used Rack/Self class to create a designer application. Created a class derived from GoGroup,IGoLabeledNode, this class is a group control consists of 1 rectangle, 1 Go Control, 1 GoText node.

Created collection of instance in the palette using this class. while dragging/dropping the instance object into the Rack grid, it is not snapping in. Also creating some duplication object in the corner of the grid… I am confused and not able to understand the issue. Appreciate your guidance on it.

Thanks,
Dinesh

Including source code.

Code to create an instance in the palette :
WinControl ctlRadioBtn = new WinControl();
ctlRadioBtn.ControlType = typeof(RadioButton);
ctlRadioBtn.Label.Text = “text”;
ctlRadioBtn.Editable = true;
ctlRadioBtn.Size = new SizeF(125, 25);
doc.Add(ctlRadioBtn)

Group Control Code.

public class WinControl : GoGroup,IGoLabeledNode
    {
        public const float UnitSize = 25;
        public WinControl()
        {
            this.AutoRescales = false;
            this.Resizable = true;
            this.ResizesRealtime = true;

            myBackground = new GoRectangle();
            myBackground.Selectable = false;
            myBackground.Brush = new HatchBrush(HatchStyle.Percent30, Color.DarkBlue, Color.White);
            Add(myBackground);

            myGoControl = new GoControl();
            myGoControl.Selectable = false;
            Add(myGoControl);

            GoText label = new GoText();
            label.Selectable = false;
            label.Multiline = false;
            label.StringTrimming = StringTrimming.EllipsisCharacter;
            label.Wrapping = true;
            label.FontSize = 9;
            label.Alignment = GoObject.MiddleCenter;
            //label.Text = "Control";
            Add(label);

        }

        public GoText Label
        {
            get { return this[2] as GoText; }
        }

        public String Text
        {
            get
            {
                GoText lab = this.Label;
                if (lab != null)
                    return lab.Text;
                return null;
            }
            set
            {
                GoText lab = this.Label;
                if (lab != null)
                    lab.Text = value;
            }
        }

        protected override void CopyChildren(GoGroup newgroup, GoCopyDictionary env)
        {
            base.CopyChildren(newgroup, env);
            WinControl cg = (WinControl)newgroup;
            cg.myBackground = (GoShape)env[myBackground];
            cg.myGoControl = (GoControl)env[myGoControl];
        }
        public override void Remove(GoObject obj)
        {
            base.Remove(obj);
            if (obj == myBackground)
                myBackground = null;
            else if (obj == myGoControl)
                myGoControl = null;
        }
        public override void LayoutChildren(GoObject childchanged)
        {
            RectangleF b = this.Bounds;
            if (this.Background != null) this.Background.Bounds = b;
            this.Background.Brush = Brushes.White;
            if (myGoControl != null)
            {
                RectangleF r = b;
                r.Inflate(-5, -5);
                myGoControl.Bounds = r;
            }
        }
        public GoShape Background
        {
            get { return myBackground; }
        }
        public GoControl GoControl
        {
            get { return myGoControl; }
        }
        public Type ControlType
        {
            get { return this.GoControl.ControlType; }
            set
            {
                // force any existing Controls to be removed
                this.GoControl.Visible = false;
                this.GoControl.ControlType = value;
                // cause any Controls to be re-created and shown
                this.GoControl.Visible = true;
            }
        }

        // An Item can be resized only in positive multiples of Item.UnitSize
        public override RectangleF ComputeResize(RectangleF origRect, PointF newPoint, int handle, SizeF min, SizeF max, bool reshape)
        {
            RectangleF r = base.ComputeResize(origRect, newPoint, handle, min, max, reshape);
            r.Width = Math.Max(1, (float)Math.Round(r.Width / UnitSize)) * UnitSize;
            r.Height = Math.Max(1, (float)Math.Round(r.Height / UnitSize)) * UnitSize;
            return r;
        }

        // change the natural Location to be the BottomLeft corner,
        // so that Items will "fall" onto Shelves appropriately
        public override PointF Location
        {
            get { return GetSpotLocation(BottomLeft); }
            set { SetSpotLocation(BottomLeft, value); }
        }

        private GoShape myBackground;
        private GoControl myGoControl;
    }

Does moving an existing WinControl object in your view snap correctly?

In other words, is the problem that the snap-to-grid behavior does not work only when dragging from another GoView, such as a GoPalette? If so, you just forgot to set GoView.ExternalDragDropsOnEnter to true.

Thanks a lot for your excellent Support!

Well… I tried creating the object in Palette and directly in View document… but both are not snapping into the Grid’s cell… The expected functionality is when moving a control from palette to view, it should snap-in. Also while moving the control inside the view… it should snap-in… both are not working.

        WinControl ctlRadioBtn = new WinControl();
        ctlRadioBtn.ControlType = typeof(RadioButton);
        ctlRadioBtn.Label.Text = "text";
        ctlRadioBtn.Editable = true;
        ctlRadioBtn.Size = new SizeF(125, 25);

        //doc.Add(ctlRadioBtn);  ***** Directly adding into the View ***

        docPalette.Add(ctlRadioBtn);  **** directly adding in the palette ****

Pl Note : . If I create an object without “GoControl” it is snap-in into the grid cell without any issues.

Let me know if you need more details or the code snippet.

Thanks,
Dinesh

I used both of your code snippets, and they worked, both when dragging from a GoPalette and when programmatically inserted into a GoDocument. But I did add a [Serializable] attribute to the class definition, which you forgot to put in your post.

Did you initialize GoView.GridSnapDrag or GoGrid.SnapDrag to the desired value?

Intresting… I am not getting it…

Code to create Object
GoDocument doc = new GoDocument();
goView1.Document = doc;

GoDocument docPalette = new GoDocument();
WinControl ctlRadioBtn = new WinControl();
ctlRadioBtn.ControlType = typeof(RadioButton);
ctlRadioBtn.Label.Text = “text”;
ctlRadioBtn.Editable = true;
ctlRadioBtn.Size = new SizeF(125, 25);
docPalette.Add(ctlRadioBtn);

Grid Code

[Serializable]
public class Rack : Display {
public Rack() {
//this.Label.Text = “Rack”;
}

protected override GoGrid CreateGrid() {
  GoGrid grid = new RackGrid();
  grid.Selectable = false;
  grid.AutoRescales = true;
  grid.Resizable = true;
  grid.ResizesRealtime = true;
  //grid.Bounds = new RectangleF(0, 0, 500, 500);
  grid.SnapDrag = GoViewSnapStyle.Jump;
  grid.SnapResize = GoViewSnapStyle.Jump;
  grid.CellSize = new SizeF(Item.UnitSize, Item.UnitSize);
  grid.Style = GoViewGridStyle.Line;
  grid.Pen = Rack.StandardPen;
  grid.Brush = null;
  return grid;
}

// make sure the Rack's Label is positioned above the top-left corner of the Grid;
// this makes it potentially useful for selection and dragging even if all of the
// grid is covered by Items
public override void LayoutChildren(GoObject childchanged) {
  if (this.Count >= 2) {
    GoGrid grid = this.Grid;
    GoText label = this.Label;
    if (grid != null && label != null) {
      label.SetSpotLocation(BottomLeft, new PointF(grid.Left, grid.Top-1));
    }
  }
}

// the Location of a Rack is actually the Position of its Grid
public override PointF Location {
  get { return this.Grid.Position; }
  set {
    SizeF off = GoTool.SubtractPoints(this.Grid.Position, this.Position);
    SizeF pos = GoTool.SubtractPoints(value, off);
    this.Position = new PointF(pos.Width, pos.Height);
  }
}

public override void SetHighlight(bool show) {
  GoGrid grid = this.Grid;
  if (grid != null) {
    if (show) {
      grid.Pen = Rack.HighlightPen;
    } else {
      grid.Pen = Rack.StandardPen;
    }
  }
}

public static readonly Pen StandardPen = new Pen(Color.Black, 2);
public static readonly Pen HighlightPen = new Pen(Color.Fuchsia, 2);

}

[Serializable]
public class RackGrid : GoGrid {
public RackGrid() {}

// the grid in a Rack only snaps Items
public override bool CanSnapPoint(PointF p, GoObject obj, GoView view) {
  if (!(obj is Item))
    return false;
  // do standard checks, such as whether the grid is a child of the OBJ,
  // the value of the grid's snap style, whether the OBJ intersects with the grid,
  // and whether the mouse point is in the grid
  return base.CanSnapPoint(p, obj, view);
}

// it can be resized only in positive multiples of Item.UnitSize
public override RectangleF ComputeResize(RectangleF origRect, PointF newPoint, int handle, SizeF min, SizeF max, bool reshape) {
  RectangleF r = base.ComputeResize(origRect, newPoint, handle, min, max, reshape);
  r.Width = Math.Max(1, (float)Math.Round(r.Width/Item.UnitSize)) * Item.UnitSize;
  r.Height = Math.Max(1, (float)Math.Round(r.Height/Item.UnitSize)) * Item.UnitSize;
  return r;
}

}

Here is the code snippet of WinControl

using System; using System.Collections.Generic; using System.Drawing.Drawing2D; using System.Text; using Northwoods.Go; using System.Drawing; // ok.. not using @this time..as it is adding more coding impact. namespace LayoutDesigner { [Serializable] public class WinControl : GoGroup,IGoLabeledNode { public const float UnitSize = 25; public WinControl() { this.AutoRescales = false; this.Resizable = true; this.ResizesRealtime = true;
            myBackground = new GoRectangle();
            myBackground.Selectable = false;
            myBackground.Brush = new HatchBrush(HatchStyle.Percent30, Color.DarkBlue, Color.White);
            Add(myBackground);

            myGoControl = new GoControl();
            myGoControl.Selectable = false;
            Add(myGoControl);

            GoText label = new GoText();
            label.Selectable = false;
            label.Multiline = false;
            label.StringTrimming = StringTrimming.EllipsisCharacter;
            label.Wrapping = true;
            label.FontSize = 9;
            label.Alignment = GoObject.MiddleCenter;
            //label.Text = "Control";
            Add(label);

        }

        public GoText Label
        {
            get { return this[2] as GoText; }
        }

        public String Text
        {
            get
            {
                GoText lab = this.Label;
                if (lab != null)
                    return lab.Text;
                return null;
            }
            set
            {
                GoText lab = this.Label;
                if (lab != null)
                    lab.Text = value;
            }
        }

        protected override void CopyChildren(GoGroup newgroup, GoCopyDictionary env)
        {
            base.CopyChildren(newgroup, env);
            WinControl cg = (WinControl)newgroup;
            cg.myBackground = (GoShape)env[myBackground];
            cg.myGoControl = (GoControl)env[myGoControl];
        }
        public override void Remove(GoObject obj)
        {
            base.Remove(obj);
            if (obj == myBackground)
                myBackground = null;
            else if (obj == myGoControl)
                myGoControl = null;
        }
        public override void LayoutChildren(GoObject childchanged)
        {
            RectangleF b = this.Bounds;
            if (this.Background != null) this.Background.Bounds = b;
            this.Background.Brush = Brushes.White;
            if (myGoControl != null)
            {
                RectangleF r = b;
                r.Inflate(-5, -5);
                myGoControl.Bounds = r;
            }
        }
        public GoShape Background
        {
            get { return myBackground; }
        }
        public GoControl GoControl
        {
            get { return myGoControl; }
        }
        public Type ControlType
        {
            get { return this.GoControl.ControlType; }
            set
            {
                // force any existing Controls to be removed
                this.GoControl.Visible = false;
                this.GoControl.ControlType = value;
                // cause any Controls to be re-created and shown
                this.GoControl.Visible = true;
            }
        }

        // An Item can be resized only in positive multiples of Item.UnitSize
        public override RectangleF ComputeResize(RectangleF origRect, PointF newPoint, int handle, SizeF min, SizeF max, bool reshape)
        {
            RectangleF r = base.ComputeResize(origRect, newPoint, handle, min, max, reshape);
            r.Width = Math.Max(1, (float)Math.Round(r.Width / UnitSize)) * UnitSize;
            r.Height = Math.Max(1, (float)Math.Round(r.Height / UnitSize)) * UnitSize;
            return r;
        }

        // change the natural Location to be the BottomLeft corner,
        // so that Items will "fall" onto Shelves appropriately
        public override PointF Location
        {
            get { return GetSpotLocation(BottomLeft); }
            set { SetSpotLocation(BottomLeft, value); }
        }

        private GoShape myBackground;
        private GoControl myGoControl;
    }

}

Thanks Again.

Your code works for me both when GoView.GridSnapStyle is set to Jump as well as when dragging into a GoSheet (in a document) whose .Grid.SnapStyle is set to Jump. I did make sure GoView.DragsRealtime and GoView.ExternalDragDropsOnEnter were true.

Xlant! It works for me… Thanks a lot for your support.

  • Dinesh