Наследование: ManipulatorHandler, ITriadManipulator, IManipulator
        protected override IEnumerable<IDisposable> AddControlsImpl()
        {
            var group = Page.CreateGroup(1, "Sample Group 1", new [] { swAddGroupBoxOptions_e.swGroupBoxOptions_Expanded ,
                swAddGroupBoxOptions_e.swGroupBoxOptions_Visible});

            yield return CreateLabel(group, "Select object", "Select object");

            yield return CreateSelectionBox(
                group,
                "Select object",
                "Select object",
                swSelectType_e.swSelSOLIDBODIES,
                _Model,
                p => p.Body,
                config =>
                {
                    config.SingleEntityOnly = true;
                    config.AllowMultipleSelectOfSameEntity = false;
                });

            yield return BodySelector()
                .SubscribeDisposable((body, yield) =>
                {
                    // The code here execute every time a new selection is made.
                    // 'yield' is an action that you pass disposable to. These disposables
                    // will be disposed before the next time this callback is activated. Thus
                    // you can use it to "unselect" or destroy any resources made by
                    // the previous selection.

                    // Copy the selected body so we can transform it
                    var newbody = (IBody2) body().Copy();
                    var mathUtility = (IMathUtility)SwApp.GetMathUtility();

                    // Create our triad. This is a custom class to make working with triads easier
                    var triad = new TriadManipulatorTs(ModelDoc); 

                    var displayedBody = newbody;

                    // Listen for changes to the axis. The subscribe callback
                    // must accept a Tuple<swTriadManipulatorControPoints_e, double> which
                    // lets you know which control point was changed and what it's
                    // current value is.
                    yield(triad.DoubleChangedObservable.Subscribe(o =>
                    {
                        var handleIndex = o.Item1;
                        var transform = triad.CreateTranslationTransform(handleIndex,mathUtility,o.Item2);

                        displayedBody.Hide(ModelDoc);
                        displayedBody = (IBody2)newbody.Copy();
                        if (!displayedBody.ApplyTransform(transform))
                            throw new Exception("Unable to shift");

                        displayedBody.DisplayTs(ModelDoc);

                        ((IModelView)ModelDoc.ActiveView).GraphicsRedraw(null);

                    }));

                    // Listen for end drag so we can move the triad to the
                    // new position.
                    yield(triad.EndDragObservable.Subscribe(handle =>
                    {
                        newbody = displayedBody;
                        SetManipulatorPositionToBodyCenter(SwApp,triad,newbody, ModelDoc);
                        GC.Collect();

                    }));

                    SetManipulatorPositionToBodyCenter(SwApp, triad, body(), ModelDoc);

                    // Show the triad and register it to be removed if the selection changes
                    triad.Show(ModelDoc);
                    yield(Disposable.Create(triad.Remove));

                    // Display the copied body and register for the current copied
                    // body to be removed if the selection changes.
                    displayedBody.DisplayTs(ModelDoc);
                    yield(Disposable.Create(() => displayedBody.Hide(ModelDoc)));

                    // Hide the selected body and register it to be shown again
                    // if the selection changes
                    yield(body().HideBodyUndoable());


                }
                , e => e.Show());
        }
 public static void SetManipulatorPositionToBodyCenter(ISldWorks sldWorks, TriadManipulatorTs manipulator, IBody2 body, IModelDoc2 model)
 {
     var box = body.GetBodyBoxTs();
     manipulator.Origin = (MathPoint) ((IMathUtility) sldWorks.GetMathUtility()).CreatePoint(box.Center.ToDoubles());
     manipulator.UpdatePosition();
 }