/// <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); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { #region TEST_1 #if TEST_1 // // you cannot create your own parameter, because the // constuctor is for internal use only. This is due // to the fact that a parameter cannot live on its own, // it is linked to a definition and needs to be hooked // up properly in the Revit database system to work // ... case 1245614 [Formatting units strings]: // bool iReallyWantToCrash = false; if (iReallyWantToCrash) { Parameter p = new Parameter(); p.Set(1.0); string s = p.AsDouble().ToString(); string t = p.AsValueString(); Debug.WriteLine("Value " + s); Debug.WriteLine("Value string " + t); } #endif // TEST #endregion // TEST_1 UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; // Loop through all pre-selected elements: foreach (ElementId id in uidoc.Selection.GetElementIds()) { Element e = doc.GetElement(id); string s = string.Empty; // set this variable to false to analyse the element's own parameters, // i.e. instance parameters for a family instance, and set it to true // to analyse a family instance's type parameters: bool analyseTypeParameters = false; if (analyseTypeParameters) { if (e is FamilyInstance) { FamilyInstance inst = e as FamilyInstance; if (null != inst.Symbol) { e = inst.Symbol; s = " type"; } } else if (e is Wall) { Wall wall = e as Wall; if (null != wall.WallType) { e = wall.WallType; s = " type"; } } // ... add support for other types if desired ... } // Loop through and list all UI-visible element parameters List <string> a = new List <string>(); #region 4.1.a Iterate over element parameters and retrieve their name, type and value: foreach (Parameter p in e.Parameters) { string name = p.Definition.Name; string type = p.StorageType.ToString(); string value = LabUtils.GetParameterValue2(p, uidoc.Document); //bool read_only = p.Definition.IsReadOnly; // 2013 bool read_only = p.IsReadOnly; // 2014 a.Add(string.Format( "Name={0}; Type={1}; Value={2}; ValueString={3}; read-{4}", name, type, value, p.AsValueString(), (read_only ? "only" : "write"))); } #endregion // 4.1.a string what = e.Category.Name + " (" + e.Id.IntegerValue.ToString() + ")"; LabUtils.InfoMsg(what + " has {0} parameter{1}{2}", a); // If we know which param we are looking for, then: // A) If a standard parameter, we can get it via BuiltInParam // signature of Parameter method: try { #region 4.1.b Retrieve a specific built-in parameter: Parameter p = e.get_Parameter( BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM); #endregion // 4.1.b if (null == p) { LabUtils.InfoMsg("FAMILY_BASE_LEVEL_OFFSET_PARAM is NOT available for this element."); } else { string name = p.Definition.Name; string type = p.StorageType.ToString(); string value = LabUtils.GetParameterValue2(p, doc); LabUtils.InfoMsg("FAMILY_BASE_LEVEL_OFFSET_PARAM: Name=" + name + "; Type=" + type + "; Value=" + value); } } catch (Exception) { LabUtils.InfoMsg("FAMILY_BASE_LEVEL_OFFSET_PARAM is NOT available for this element."); } // B) For a shared parameter, we can get it via "GUID" signature // of Parameter method ... this will be shown later in Labs 4 ... // C) or we can get the parameter by name: // alternatively, loop through all parameters and // search for the name (this works for either // standard or shared). Note that the same name // may occur multiple times: const string paramName = "Base Offset"; //Parameter parByName = e.get_Parameter( paramName ); // 2014 IList <Parameter> paramsByName = e.GetParameters(paramName); // 2015 if (0 == paramsByName.Count) { LabUtils.InfoMsg(paramName + " is NOT available for this element."); } else { foreach (Parameter p in paramsByName) { string parByNameName = p.Definition.Name; string parByNameType = p.StorageType.ToString(); string parByNameValue = LabUtils.GetParameterValue2(p, doc); LabUtils.InfoMsg(paramName + ": Name=" + parByNameName + "; Type=" + parByNameType + "; Value=" + parByNameValue); } } #region TEST_2 #if TEST_2 List <string> a = GetParameters(doc, e); foreach (string s2 in a) { Debug.WriteLine(s2); } #endif // TEST_2 #endregion // TEST_2 } return(Result.Failed); }