BuildingCoder.CmdMirrorListAdded.Execute C# (CSharp) Method

Execute() public method

public Execute ( ExternalCommandData commandData, string &message, ElementSet elements ) : System.Result
commandData ExternalCommandData
message string
elements ElementSet
return System.Result
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
              UIDocument uidoc = uiapp.ActiveUIDocument;
              Application app = uiapp.Application;
              Document doc = uidoc.Document;

              using ( Transaction tx = new Transaction( doc ) )
              {
            tx.Start( "Mirror and List Added" );
            //Line line = app.Create.NewLine(
            //  XYZ.Zero, XYZ.BasisX, true ); // 2011

            //ElementSet els = uidoc.Selection.Elements; // 2011

            //Plane plane = new Plane( XYZ.BasisY, XYZ.Zero ); // added in 2012, used until 2016

            Plane plane = Plane.CreateByNormalAndOrigin( XYZ.BasisY, XYZ.Zero ); // 2017

            ICollection<ElementId> elementIds
              = uidoc.Selection.GetElementIds(); // 2012

            using ( SubTransaction t = new SubTransaction( doc ) )
            {
              // determine newly added elements relying on the
              // element sequence as returned by the filtered collector.
              // this approach works in both Revit 2010 and 2011:

              t.Start();

              int n = GetElementCount( doc );

              //doc.Mirror( els, line ); // 2011

              //ElementTransformUtils.MirrorElements(
              //  doc, elementIds, plane ); // 2012-2015

              ElementTransformUtils.MirrorElements(
            doc, elementIds, plane, true ); // 2016

              List<Element> a = GetElementsAfter( n, doc );

              t.RollBack();
            }

            using ( SubTransaction t = new SubTransaction( doc ) )
            {
              // here is an idea for a new approach in 2011:
              // determine newly added elements relying on
              // monotonously increasing element id values:

              t.Start();

              FilteredElementCollector a = GetElements( doc );
              int i = a.Max<Element>( e => e.Id.IntegerValue );
              ElementId maxId = new ElementId( i );

              // doc.Mirror( els, line ); // 2011

              //ElementTransformUtils.MirrorElements(
              //  doc, elementIds, plane ); // 2012-2015

              ElementTransformUtils.MirrorElements(
            doc, elementIds, plane, true ); // 2016

              // get all elements in document with an
              // element id greater than maxId:

              a = GetElementsAfter( doc, maxId );

              Report( a );

              t.RollBack();
            }

            using ( SubTransaction t = new SubTransaction( doc ) )
            {
              // similar to the above approach relying on
              // monotonously increasing element id values,
              // but apply a quick filter first:

              t.Start();

              FilteredElementCollector a = GetElements( doc );
              int i = a.Max<Element>( e => e.Id.IntegerValue );
              ElementId maxId = new ElementId( i );

              //doc.Mirror( els, line ); // 2011

              //ElementTransformUtils.MirrorElements(
              //  doc, elementIds, plane ); // 2012-2015

              ElementTransformUtils.MirrorElements(
            doc, elementIds, plane, true ); // 2016

              // only look at non-ElementType elements
              // instead of all document elements:

              a = GetElements( doc );
              a = GetElementsAfter( a, maxId );

              Report( a );

              t.RollBack();
            }

            using ( SubTransaction t = new SubTransaction( doc ) )
            {
              // use a local and temporary DocumentChanged event
              // handler to directly obtain a list of all newly
              // created elements.
              // unfortunately, this canot be tested in this isolated form,
              // since the DocumentChanged event is only triggered when the
              // real outermost Revit transaction is committed, i.e. our
              // local sub-transaction makes no difference. since we abort
              // the sub-transaction before the command terminates and no
              // elements are really added to the database, our event
              // handler is never called:

              t.Start();

              app.DocumentChanged
            += new EventHandler<DocumentChangedEventArgs>(
              app_DocumentChanged );

              //doc.Mirror( els, line ); // 2011

              //ElementTransformUtils.MirrorElements(
              //  doc, elementIds, plane ); // 2012-2015

              ElementTransformUtils.MirrorElements(
            doc, elementIds, plane, true ); // 2016

              app.DocumentChanged
            -= new EventHandler<DocumentChangedEventArgs>(
              app_DocumentChanged );

              Debug.Assert( null == _addedElementIds,
            "never expected the event handler to be called" );

              if ( null != _addedElementIds )
              {
            int n = _addedElementIds.Count;

            string s = string.Format( _msg, n,
              Util.PluralSuffix( n ) );

            foreach ( ElementId id in _addedElementIds )
            {
              Element e = doc.GetElement( id );

              s += string.Format( "\r\n  {0}",
                Util.ElementDescription( e ) );
            }
            Util.InfoMsg( s );
              }

              t.RollBack();
            }
            tx.RollBack();
              }
              return Result.Succeeded;
        }