如何通过Revit API控制载入族与创建类型事件?求技术指引
Hey there! Let’s walk through how you can take control of Load Families and Create Type events with the Revit API—no confusing jargon, just practical, actionable steps based on real-world use cases.
First, you need to understand Revit’s event-driven model: there are pre-action events (triggered before an operation happens, let you cancel or modify it) and post-action events (triggered after, for follow-up tasks). We’ll use both depending on what you want to control.
1. Controlling Family Load Events
If you want to block certain families from being loaded, validate their properties before they’re added to the project, or automate tasks after loading, these are the events you need:
Pre-Family Load (Block/Validate Before Loading)
Use the Application.PreFamilyLoad event—it fires right before Revit loads a family, so you can cancel the operation if the family doesn’t meet your rules.
Here’s a quick code snippet to register and handle it (best done in an IExternalApplication so it runs for the entire Revit session):
public class FamilyControlApp : IExternalApplication { public Result OnStartup(UIControlledApplication uiApp) { // Register the pre-load event uiApp.Application.PreFamilyLoad += OnPreFamilyLoad; return Result.Succeeded; } public Result OnShutdown(UIControlledApplication uiApp) { // Always unregister events to avoid memory leaks/crashes uiApp.Application.PreFamilyLoad -= OnPreFamilyLoad; return Result.Succeeded; } private void OnPreFamilyLoad(object sender, PreFamilyLoadEventArgs e) { // Get the family being loaded Family familyToLoad = e.Family; // Example: Block all door families if (familyToLoad.FamilyCategory.Name.Equals("Doors")) { e.Cancel = true; TaskDialog.Show("Family Blocked", "Door families are not allowed in this project."); } } }
Post-Family Load (Automate Tasks After Loading)
If you need to modify the loaded family (add parameters, set defaults) or log the load, use Application.FamilyLoaded. This fires after the family is successfully added to the project.
private void OnFamilyLoaded(object sender, FamilyLoadedEventArgs e) { Family loadedFamily = e.LoadedFamily; // Example: Add a custom parameter to the loaded family using (Transaction trans = new Transaction(loadedFamily.Document, "Add Custom Param")) { trans.Start(); FamilyParameter newParam = loadedFamily.FamilyManager.AddParameter( "ProjectID", BuiltInParameterGroup.PG_IDENTITY_DATA, ParameterType.Text, false); trans.Commit(); } }
2. Controlling Type Creation Events
For creating new element types (like a new door type from a loaded family), you have two key events to use:
Pre-Type Creation (Block Invalid Types)
Use ControlledApplication.PreCreate to intercept type creation before it happens. You’ll need to filter for ElementType since this event fires for all element types.
public Result OnStartup(UIControlledApplication uiApp) { ControlledApplication controlledApp = uiApp.ControlledApplication; controlledApp.PreCreate += OnPreElementTypeCreate; return Result.Succeeded; } private void OnPreElementTypeCreate(object sender, PreCreateEventArgs e) { // Check if the element being created is an ElementType if (e.CreatingElement is ElementType newType) { // Example: Block types with empty names if (string.IsNullOrWhiteSpace(newType.Name)) { e.Cancel = true; TaskDialog.Show("Type Creation Blocked", "Type names cannot be empty."); } } }
Post-Type Creation (Automate Configuration)
Use Application.ElementTypeCreated to modify or configure the new type after it’s created.
private void OnElementTypeCreated(object sender, ElementTypeCreatedEventArgs e) { ElementType newType = e.ElementType; // Example: Set a default value for a parameter Parameter widthParam = newType.LookupParameter("Width"); if (widthParam != null && widthParam.IsReadOnly == false) { using (Transaction trans = new Transaction(newType.Document, "Set Default Width")) { trans.Start(); widthParam.Set(1200); // Set width to 1200mm trans.Commit(); } } }
- Always unregister events: Failing to do so in
OnShutdownwill cause memory leaks or Revit crashes. - Transactions are mandatory: Any modification to Revit elements (even in event handlers) must be wrapped in a
Transaction. - Use
IExternalApplicationfor persistent control: If you register events in anIExternalCommand, they’ll only work while that command is running. For session-wide control, useIExternalApplication. - Test with RevitLookup: This tool lets you inspect families, types, and their parameters to understand what data you can access in events.
内容的提问来源于stack exchange,提问作者Tiago Cerqueira

