Hello Revit gurus,
I am new to C# programming and for the past 2 days I couldn't find the solution for my problem. I have created an External addin that add tags to family instances based on its BuiltinCategory. The addin works as it should without any problems. However when I decided to create a form to expand the functionality of the addin that is when the headaches started.
I cut down my program into 3 parts. The first implements the ExternalCommandData method to show the form.
using System; using System.Windows.Forms; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Plumbing; using Autodesk.Revit.UI; using Autodesk.Revit.DB.Architecture; using Autodesk.Revit.UI.Selection; namespace Pipes_Annotations1 { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] [Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)] public class pipesannotation1 : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { //tagging tagginng1 = new tagging(commandData); try { tagging m_tagging = new tagging(); // show UI using (Form1 displayForm = new Form1(m_tagging,commandData)) { DialogResult result = displayForm.ShowDialog(); if (DialogResult.OK != result) { return Autodesk.Revit.UI.Result.Cancelled; } } return Autodesk.Revit.UI.Result.Succeeded; } catch (Exception e) { message = e.Message; return Autodesk.Revit.UI.Result.Failed; } } } }
The Second Part creates the tags:
namespace Pipes_Annotations1 { public class tagging { public FamilySymbol elemtag1 = null; public FamilySymbol elemtag2 = null; public void tagging1(ExternalCommandData commandData) { MessageBox.Show("Started the program"); try { // Get the active document and view UIDocument revitDoc = commandData.Application.ActiveUIDocument; Autodesk.Revit.DB.View view = revitDoc.Document.ActiveView; StringBuilder message2 = new StringBuilder(); FilteredElementCollector viewCollector = new FilteredElementCollector(revitDoc.Document, revitDoc.ActiveView.Id); viewCollector.OfCategory(BuiltInCategory.OST_PipeCurves); message2.AppendLine("Pipes category elements within active View: " + viewCollector.ToElementIds().Count); FilteredElementCollector docCollector = new FilteredElementCollector(revitDoc.Document); docCollector.OfCategory(BuiltInCategory.OST_PipeCurves); message2.AppendLine("Pipes category elements within document: " + docCollector.ToElementIds().Count); FilteredElementCollector Familytagcollector = new FilteredElementCollector(revitDoc.Document); Familytagcollector.OfCategory(BuiltInCategory.OST_PipeTags); Familytagcollector.OfClass(typeof(FamilySymbol)); message2.AppendLine("Pipes tags category elements within document: " + Familytagcollector.ToElementIds().Count); TaskDialog.Show("Revit", message2.ToString()); foreach (ElementId tagID in Familytagcollector.ToElementIds()) { FamilySymbol elemtag = revitDoc.Document.GetElement(tagID) as FamilySymbol; Parameter elemtagfam = elemtag.get_Parameter(BuiltInParameter.ELEM_FAMILY_PARAM); if (elemtag.Family.Name == "Pipe Size Tag") { elemtag1 = elemtag; MessageBox.Show(elemtag.Family.Name); } else if (elemtag.Family.Name == "BOP") { elemtag2 = elemtag; MessageBox.Show(elemtag.Family.Name); } } string message = ""; if (viewCollector.ToElementIds().Count == 0) { message = "No pipe selected!"; MessageBox.Show(message); } else { foreach (ElementId elemId in viewCollector.ToElementIds()) { message = " " + elemId; Element elem = revitDoc.Document.GetElement(elemId); if (elem.GetType() == typeof(Autodesk.Revit.DB.Plumbing.Pipe)) { Autodesk.Revit.DB.Plumbing.Pipe pipe = (Autodesk.Revit.DB.Plumbing.Pipe)elem; LocationCurve pipelloc = pipe.Location as LocationCurve; XYZ pipeStart = pipelloc.Curve.GetEndPoint(0); XYZ pipeEnd = pipelloc.Curve.GetEndPoint(1); XYZ pipeMid = pipelloc.Curve.Evaluate(0.5, true); using (Transaction t = new Transaction(revitDoc.Document)) { t.Start("Create new tag"); IndependentTag tag = revitDoc.Document.Create.NewTag(view, pipe, false, Autodesk.Revit.DB.TagMode.TM_ADDBY_CATEGORY, Autodesk.Revit.DB.TagOrientation.Horizontal, pipeMid ); tag.ChangeTypeId(elemtag1.Id); t.Commit(); } } } } } catch (Exception err) { string message = err.Message; //return Autodesk.Revit.UI.Result.Failed; } } } }
The 3rd part is the form. In the form Structure under the button1_Click method, I added the tagging method only without ending this.Close();. The program works as it should and the tags are added. However, when I close the form manually, all my tags disappear. If I add this.Close(); after the tagging method, the program runs but none of the tags appear. So I am assuming that closing the form does not commit the transaction and whenever I close it all the tags disappear. I am not sure How to solve this issue and any help will be appreciated. the form code:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Plumbing; using Autodesk.Revit.UI; using Autodesk.Revit.DB.Architecture; using Autodesk.Revit.UI.Selection; namespace Pipes_Annotations1 { //[TransactionAttribute(TransactionMode.Manual)] //[RegenerationAttribute(RegenerationOption.Manual)] public partial class Form1 : System.Windows.Forms.Form { private tagging m_tagging1; ExternalCommandData commandData; public Form1(tagging m_tagging, ExternalCommandData commandData1) { m_tagging1 = m_tagging; commandData = commandData1; InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { m_tagging1.tagging1(commandData);
} private void Form1_Load(object sender, EventArgs e) { } private void button2_Click(object sender, EventArgs e) { this.Close(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { //System.Windows.Forms.Application.Exit(); } private void groupBox1_Enter(object sender, EventArgs e) { } } }
Thank you so much
Nayer Girgis