public void Copy() { // Things that we should consider: // - when copy an object that is selected, we must save its absolute position instead of relative Top, Left. // This is necessary when copying several objects that have different parents. // - when copy a parent object and its child, and both are selected, we must exclude a child from the // selected objects. This is necessary to avoid duplicate copy of the child object - it will be // copied by its parent. if (FDesigner.SelectedObjects == null) { return; } using (ClipboardParent parent = new ClipboardParent()) { Hashtable bounds = new Hashtable(); parent.PageType = FDesigner.SelectedObjects[0].Page.GetType(); foreach (Base c in FDesigner.Objects) { if (c.IsSelected) { if (c.HasFlag(Flags.CanCopy)) { if (!parent.Contains(c)) { if (c is ComponentBase) { ComponentBase c1 = c as ComponentBase; bounds[c1] = c1.Bounds; c1.SetDesigning(false); c1.Left = c1.AbsLeft; c1.Top = c1.AbsTop; } parent.Objects.Add(c); } } } } using (MemoryStream stream = new MemoryStream()) using (FRWriter writer = new FRWriter()) { writer.SerializeTo = SerializeTo.Clipboard; writer.Write(parent); writer.Save(stream); Clipboard.SetData("FastReport", stream); } // restore components' state foreach (Base c in parent.Objects) { if (c is ComponentBase) { ComponentBase c1 = c as ComponentBase; if (bounds[c1] != null) { c1.Bounds = (RectangleF)bounds[c1]; } c1.SetDesigning(true); } } } }