Files
SzmediTools/Szmedi.RvKits/Assists/ParameterHelper.cs
2025-09-16 16:06:41 +08:00

143 lines
5.5 KiB
C#

using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
namespace RevitAddin.Helpers
{
/// <summary>
/// Helper class for creating and managing read-only shared parameters and adding family parameters in Revit 2020.
/// </summary>
public static class ParameterHelper
{
/// <summary>
/// Adds a shared parameter to the document with UI disabled (read-only).
/// </summary>
/// <param name="commandData">External command data.</param>
/// <param name="doc">The target document.</param>
/// <param name="paramName">Name of the parameter.</param>
/// <param name="paramType">ParameterType for the shared parameter.</param>
/// <param name="groupName">Group in shared parameter file.</param>
/// <param name="categories">Categories to bind the parameter to.</param>
/// <param name="instanceBinding">True for instance binding; false for type binding.</param>
/// <returns>True if binding succeeded; otherwise false.</returns>
public static bool AddReadOnlySharedParameter(
ExternalCommandData commandData,
Document doc,
string paramName,
ParameterType paramType,
string groupName,
BuiltInCategory[] categories,
bool instanceBinding = true)
{
UIApplication uiApp = commandData.Application;
var app = uiApp.Application;
// Open shared parameter file
DefinitionFile sharedFile = app.OpenSharedParameterFile();
if (sharedFile == null)
throw new InvalidOperationException("Shared parameter file not found.");
// Get or create group
DefinitionGroup group = sharedFile.Groups.get_Item(groupName)
?? sharedFile.Groups.Create(groupName);
// Create definition with read-only setting
var options = new ExternalDefinitionCreationOptions(paramName, paramType)
{
UserModifiable = false,
Visible = true,
Description = "Read-only shared parameter"
};
Definition definition = group.Definitions.Create(options);
// Prepare category set
CategorySet catSet = app.Create.NewCategorySet();
foreach (BuiltInCategory bic in categories)
{
Category cat = Category.GetCategory(doc, bic);
if (cat != null)
catSet.Insert(cat);
}
// Create binding
Binding binding = instanceBinding
? (Binding)app.Create.NewInstanceBinding(catSet)
: app.Create.NewTypeBinding(catSet);
// Insert into document
using (Transaction tx = new Transaction(doc, "Add Read-Only Shared Parameter"))
{
tx.Start();
bool bound = doc.ParameterBindings.Insert(definition, binding, BuiltInParameterGroup.PG_IDENTITY_DATA);
tx.Commit();
return bound;
}
}
/// <summary>
/// Removes a shared parameter binding and definition from the document.
/// </summary>
/// <param name="doc">The document to modify.</param>
/// <param name="paramName">Name of the parameter to remove.</param>
public static void RemoveSharedParameter(Document doc, string paramName)
{
BindingMap bindingMap = doc.ParameterBindings;
DefinitionBindingMapIterator iter = bindingMap.ForwardIterator();
Definition toRemove = null;
// Iterate through bindings to find definition by name
for (iter.Reset(); iter.MoveNext();)
{
Definition def = iter.Key;
if (def != null && def.Name.Equals(paramName, StringComparison.OrdinalIgnoreCase))
{
toRemove = def;
break;
}
}
if (toRemove == null)
throw new InvalidOperationException($"Shared parameter '{paramName}' not found.");
// Remove binding
using (Transaction tx = new Transaction(doc, "Remove Shared Parameter"))
{
tx.Start();
bindingMap.Remove(toRemove);
tx.Commit();
}
}
/// <summary>
/// Adds a family parameter to a family document (Revit 2020).
/// Note: Revit 2020 API does not support setting family parameters to read-only via API.
/// </summary>
/// <param name="familyDoc">The family document.</param>
/// <param name="paramName">Name of the family parameter.</param>
/// <param name="group">Parameter group.</param>
/// <param name="paramType">Parameter type.</param>
/// <param name="isInstance">True for instance parameter; false for type parameter.</param>
/// <returns>The created FamilyParameter.</returns>
public static FamilyParameter AddFamilyParameter(
Document familyDoc,
string paramName,
BuiltInParameterGroup group,
ParameterType paramType,
bool isInstance)
{
FamilyManager fm = familyDoc.FamilyManager;
using (Transaction tx = new Transaction(familyDoc, "Add Family Parameter"))
{
tx.Start();
FamilyParameter fp = fm.AddParameter(paramName, group, paramType, isInstance);
tx.Commit();
return fp;
}
}
}
}