I'm trying to create a command that when a user clicks on a tag in Revit, the command will change the label color in the tag. I'm an experienced programmer but Revit newbie.
Here's my code:
// get annotation type ElementId elTypeId = el.GetTypeId(); if (elTypeId == null) throw new ErrorMessageException("Error getTypeId"); FamilySymbol elType = doc.GetElement(elTypeId) as FamilySymbol; if (elType == null) throw new ErrorMessageException("Error getType"); // get the annotation family Family tagFamily = elType.Family; if(tagFamily == null) throw new ErrorMessageException("Error get tag family"); if (!tagFamily.IsEditable) throw new ErrorMessageException("Error unable to edit tag family"); // determine if this is a system or standard (i.e. external file) family // NOTE: not sure but all tags are external files? Document tagDoc = doc.EditFamily(tagFamily); if (tagDoc != null && tagDoc.IsFamilyDocument == true) { // get label(s) FilteredElementCollector collector = new FilteredElementCollector(tagDoc); ICollection<Element> labels = collector.OfClass(typeof(TextElement)).ToElements(); if (labels.Count == 0) throw new ErrorMessageException("Error tag has no label"); foreach (Element label in labels) { // get label type ElementId elLabelTypeId = label.GetTypeId(); if (elLabelTypeId == null) throw new ErrorMessageException("Error elLabelTypeId"); //FamilySymbol elLabelType = tagDoc.GetElement(elLabelTypeId) as FamilySymbol; // returns null Element elLabelType = tagDoc.GetElement(elLabelTypeId); if (elLabelType == null) throw new ErrorMessageException("Error elLabelType"); String strTypeName = elLabelType.Name; if (strTypeName.Contains("zdlink")) continue; String strLinkTypeName = strTypeName + " zdlink"; /* // get label family Family labelFamily = elLabelType.Family; if (labelFamily == null) throw new ErrorMessageException("Error get label family"); */ // get all possible label types ICollection<ElementId> cTypes = label.GetValidTypes(); // search for our zdlink label type Element elLinkType = null; ElementType newType = null; foreach (ElementId availTypeId in cTypes) { // get element Element elTemp = tagDoc.GetElement(availTypeId); // check if this is our type if (elTemp.Name == strLinkTypeName) { elLinkType = elTemp; newType = elLinkType as ElementType; } } // new Transaction Transaction trans = null; //if (labelFamily.IsInPlace) trans = new Transaction(doc); //else //trans = new Transaction(tagDoc); // fails for Wall Tag trans.Start("Create new label type " + strLinkTypeName); // create new zdlink label type if it doesn't exist if (elLinkType == null) { // duplicate type ElementType existingType = elType as ElementType; // create new type newType = existingType.Duplicate(strLinkTypeName); if (newType == null) throw new ErrorMessageException("Error newType"); // change color Parameter pTextColor = newType.get_Parameter(BuiltInParameter.TEXT_COLOR); if (pTextColor != null) { System.Drawing.Color linkColor = new System.Drawing.Color(); linkColor = System.Drawing.Color.FromArgb(App.m_linkColor.Red, App.m_linkColor.Green, App.m_linkColor.Blue); int nRGB = System.Drawing.ColorTranslator.ToWin32(linkColor); pTextColor.Set(nRGB); } Parameter pLineColor = newType.get_Parameter(BuiltInParameter.LINE_COLOR); if (pLineColor != null) { System.Drawing.Color linkColor = new System.Drawing.Color(); linkColor = System.Drawing.Color.FromArgb(App.m_linkColor.Red, App.m_linkColor.Green, App.m_linkColor.Blue); int nRGB = System.Drawing.ColorTranslator.ToWin32(linkColor); pLineColor.Set(nRGB); } } // change elements type label.ChangeTypeId(newType.Id); trans.Commit(); } } else throw new ErrorMessageException("Error tag family not external file");
At the beginning el is the selected tag in the main project. In this case I have a simple wall tag loaded from the default wall tag annotation file.
I get this message in Revit: "The type typeid is not valid for this element. Parameter name typeid". When stepping through the code it occurrs on the line with "label.ChangeTYpeId(newTYpe.id)".
Dear Randall,
Wow, that looks awfully complicated.
I guess that's the way it is, more or less.
There are a huge number of different ways to control an element's colour, though, so you need to decide sensibly which approach you wish to use before you start implementing it:
http://thebuildingcoder.typepad.com/blog/2013/08/attributes-relationships-and-other-stuff.html#6
The element id of the label tag type needs to refer to a valid label tag type element.
To find out which one is valid, you should set up the required situation manually through the user interface first and explore it using RevitLookup. That will show you which values to use.
Best regards,
Jeremy