I'm wondering if all parameters found on a FamilyInstance are by definition family parameters or if it is possible for some of them to be project parameters applied to the family, and if so, how do you tell the difference between the two?
So for example, if you use the following code to filter out just the FamilyInstance objects and look at their associated parameters:
ElementClassFilter FamilyInstanceFilter = new ElementClassFilter(typeof(FamilyInstance));
FilteredElementCollector FamilyInstanceCollector = new FilteredElementCollector(RvtDoc);
ICollection<Element> AllFamilyInstances = FamilyInstanceCollector.WherePasses(FamilyInstance
foreach (FamilyInstance FmlyInst in AllFamilyInstances)
FmlySmbl = FmlyInst.Symbol;
Fmly = FmlySmbl.Family;
// Look through the following ParameterSets (valid code has been left out)
Will any of the parameters from the ParameterSets above be Project Parameters? If so, what property of the Parameter class tells you whether you have a Family Parameter or Project Parameter?
Conversely, if none of them can be Project Parameters, then how does one get at the Project Parameters added to a particular Family or is that not possible to do?
Solved! Go to Solution.
Just adding to my question above, I have determined that by checking those 3 ParameterSets in the code above, I do get Project parameters, Family parameters, and Shared parameters (both Type and Instance).
So my question remains, how does one use the Revit Api's Parameter class to determine if the parameter is a Project parameter or Family parameter (the IsShared property tells us if it is a Shared parameter). Also, how do you tell if it is a Type or Instance parameter?
Thanks for the help!
So now the question is how to tell the difference between the project parameter and family parameter, and for a given parameter how to judge if it is a instance parameter or type parameter.
1. For a project parameter, there is a corresponding parameter definition binding item in the document. All the parameter binding items can be retrieved via Document.ParameterBindings property. It returns BindingMap object, the collection of all the bindings for this project, . You can loop this collection, compare the binding item's name with your target parameter name, if you cannot fine the corresponding binding name with the target parameter name, than this parameter should be family parameter. There is a binding's name is equal to your target parameter name, then it is likely to be the project parameter. (As project parameter can have the duplicate names, so here i use the likely)
2. From the above project parameter, you can find a binding object matching to this parameter. You can cast this Binding object to ElementBinding object. Then cast the ElementBinding object to InstanceBinding or TypeBinding. Because the InstanceBinding class and TypeBinding class derive from ElementBinding class.
If it can be cast to InstanceBinding object, then this parameter is for instance. Otherwise it is type parameter.
Hope this explains.
Thanks for the reply Joe! I had just recently learnded about the Document.ParameterBindings you mention and the fact that this is indeed the list of Project Parameters. So that is very helpful. From everything I've learned, it looks like your suggestion is the best approach. As you mentioned, not finding a match by name in this list guarantees we are dealing with a Family parameter. Finding a match means it is likely a Project parameter, but not guaranteed since you could have a parameter with the same name defined in both the project and the family.
I was also investigating opening the Revit Family to check its parameters using the Document.EditFamily method, but this causes a serious performance hit and lead to another question. I was wondering if you could comment on this scenario:
Assume you have a Revit project file with a family that contains a parameter named TEST_PARAM, and you also have a project parameter defined named TEST_PARAM that is associated with the same category as that family (so there are 2 TEST_PARAM parameters on the family, one from the family itself and one from the project). Am I correct in thinking that it is impossible to determine which one of these TEST_PARAM parameters came from the family, and which one came from the project?
In all of my testing, even when opening the Family Project file directly, I've found no way to correctly associate the two other than by name, which is not reliable since the name can be identical across the parameters of the project and family. In my testing, the IDs of the parameters are not the same when comparing the FamilyParameter objects from the family file with Parameter objects of the same name from the project file. Is this true?
Thanks for your help!
If a family instance contains Project Parameter namedTEST_PARAM, and also the family parameter named TEST_PARAM. Still we can use the parameter's host Group and the parameter storage type to identify their difference.
However if both the parameter group and the storage type are identical, no more feature can tell the different between parameter which is the project one and which is the family parameter.
Revit didn't provide the mechnism to prevent identical parameter names, so please avoid adding the duplicate parameter name for the same category via API.
Thanks again for your input. We were tasked with creating a utility to locate problems in parameters (duplicate names or missing parameters) and display them to the user. We don't ever create the duplicate names ourselves, but users sometimes do, so this tool is to help them locate the problems so they can fix them.
The tool is designed to do the following:
Thanks for the help you provided, it is much appreciated!