public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; UIDocument uidoc = app.ActiveUIDocument; Document doc = uidoc.Document; FamilyInstance inst = LabUtils.GetSingleSelectedElementOrPrompt( uidoc, typeof(FamilyInstance)) as FamilyInstance; if (null == inst) { LabUtils.ErrorMsg( "Selected element is not a " + "standard family instance."); return(Result.Cancelled); } // determine selected instance category: Category instCat = inst.Category; Dictionary <string, List <FamilySymbol> > mapFamilyToSymbols = new Dictionary <string, List <FamilySymbol> >(); { WaitCursor waitCursor = new WaitCursor(); // Collect all types applicable to this category and sort them into // a dictionary mapping the family name to a list of its types. // // We create a collection of all loaded families for this category // and for each one, the list of all loaded types (symbols). // // There are many ways how to store the matching objects, but we choose // whatever is most suitable for the relevant UI. We could use Revit's // generic Map class, but it is probably more efficient to use the .NET // strongly-typed Dictionary with // KEY = Family name (String) // VALUE = list of corresponding FamilySymbol objects // // find all corresponding families and types: FilteredElementCollector families = new FilteredElementCollector(doc); families.OfClass(typeof(Family)); foreach (Family f in families) { bool categoryMatches = false; ISet <ElementId> ids = f.GetFamilySymbolIds(); // 2015 // we cannot trust f.Category or // f.FamilyCategory, so grab the category // from first family symbol instead: //foreach( FamilySymbol sym in f.Symbols ) // 2014 foreach (ElementId id in ids) // 2015 { Element symbol = doc.GetElement(id); categoryMatches = symbol.Category.Id.Equals( instCat.Id); break; } if (categoryMatches) { List <FamilySymbol> symbols = new List <FamilySymbol>(); //foreach( FamilySymbol sym in f.Symbols ) // 2014 foreach (ElementId id in ids) // 2015 { FamilySymbol symbol = doc.GetElement(id) as FamilySymbol; symbols.Add(symbol); } mapFamilyToSymbols.Add(f.Name, symbols); } } } // display the form allowing the user to select // a family and a type, and assign this type // to the instance. Lab3_4_Form form = new Lab3_4_Form(mapFamilyToSymbols); if (System.Windows.Forms.DialogResult.OK == form.ShowDialog()) { using (Transaction t = new Transaction(doc)) { t.Start("Change Selected Instance Type"); inst.Symbol = form.cmbType.SelectedItem as FamilySymbol; t.Commit(); } LabUtils.InfoMsg( "Successfully changed family : type to " + form.cmbFamily.Text + " : " + form.cmbType.Text); } return(Result.Succeeded); }
/// <summary> /// Revit external command to list all valid built-in parameters for a given selected element. /// </summary> public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; Element e = LabUtils.GetSingleSelectedElementOrPrompt( uidoc); if (null == e) { return(Result.Cancelled); } bool isSymbol = false; #region Check for FamilyInstance #if CHECK_FOR_FAMILY_INSTANCE // // for a family instance, ask user whether to // display instance or type parameters; // in a similar manner, we could add dedicated // switches for Wall --> WallType, // Floor --> FloorType etc. ... // if (e is FamilyInstance) { FamilyInstance inst = e as FamilyInstance; if (null != inst.Symbol) { string symbol_name = LabUtils.ElementDescription( inst.Symbol, true); string family_name = LabUtils.ElementDescription( inst.Symbol.Family, true); string msg = "This element is a family instance, so it " + "has both type and instance parameters. " + "By default, the instance parameters are " + "displayed. If you select 'No', the type " + "parameters will be displayed instead. " + "Would you like to see the instance " + "parameters?"; if (!LabUtils.QuestionMsg(msg)) { e = inst.Symbol; isSymbol = true; } } } #endif // CHECK_FOR_FAMILY_INSTANCE #endregion // Check for FamilyInstance #region Check for element type #if CHECK_GET_TYPE_ID ElementId idType = e.GetTypeId(); if (ElementId.InvalidElementId != idType) { // The selected element has a type; ask user // whether to display instance or type // parameters. ElementType typ = doc.GetElement(idType) as ElementType; Debug.Assert(null != typ, "expected to retrieve a valid element type"); string type_name = LabUtils.ElementDescription( typ, true); string msg = "This element has an ElementType, so it has " + "both type and instance parameters. By " + "default, the instance parameters are " + "displayed. If you select 'No', the type " + "parameters will be displayed instead. " + "Would you like to see the instance " + "parameters?"; if (!LabUtils.QuestionMsg(msg)) { e = typ; isSymbol = true; } } #endif // CHECK_GET_TYPE_ID #endregion // Check for element type SortableBindingList <ParameterData> data = new SortableBindingList <ParameterData>(); { WaitCursor waitCursor = new WaitCursor(); Array bips = Enum.GetValues(typeof(BuiltInParameter)); int n = bips.Length; Parameter p; foreach (BuiltInParameter a in bips) { try { p = e.get_Parameter(a); #region Check for external definition #if CHECK_FOR_EXTERNAL_DEFINITION Definition d = p.Definition; ExternalDefinition e = d as ExternalDefinition; // this is never possible string guid = (null == e) ? null : e.GUID.ToString(); #endif // CHECK_FOR_EXTERNAL_DEFINITION #endregion // Check for external definition if (null != p) { //string value = LabUtils.GetParameterValue2( p, doc ); string valueString = (StorageType.ElementId == p.StorageType) ? LabUtils.GetParameterValue2(p, doc) : p.AsValueString(); data.Add(new ParameterData(a, p, valueString)); } } catch (Exception ex) { Debug.Print("Exception retrieving built-in parameter {0}: {1}", a, ex); } } } string description = LabUtils.ElementDescription(e, true) + (isSymbol ? " Type" : " Instance"); using (BuiltInParamsCheckerForm form = new BuiltInParamsCheckerForm(description, data)) { form.ShowDialog(); } return(Result.Succeeded); }