You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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.

Core Event Types to Focus On

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();
        }
    }
}
Critical Best Practices
  • Always unregister events: Failing to do so in OnShutdown will 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 IExternalApplication for persistent control: If you register events in an IExternalCommand, they’ll only work while that command is running. For session-wide control, use IExternalApplication.
  • 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:51:22