当我手动使用 Loadfamily 选项时,类型目录弹出窗口如下图所示。
但是通过 Revit api 编程,使用 Loadfamily() api 函数时弹出窗口不会出现。即使所需的 .TXT 文件在同一工作目录中可用。
您能帮助我们克服这个问题吗?
提前感谢您的支持
我认为不可能以编程方式启动与内置“加载族”命令分开的类型目录对话框。这给你两个选择:
PostCommand
请注意,每次 PostCommand
执行只能使用一次
IExternalCommand
[Transaction(TransactionMode.Manual)]
public class LoadFamilyWithTypeCatalog : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
var commandId = RevitCommandId.LookupCommandId("ID_FAMILY_LOAD");
commandData.Application.PostCommand(commandId);
return Result.Succeeded;
}
}
[Transaction(TransactionMode.Manual)]
public class LoadFamilyWithTypeCatalog_CustomUI : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
var doc = commandData.Application.ActiveUIDocument.Document;
var path = @"C:\StackOverflow\Box.rfa";
using (var t = new Transaction(doc, "Load Family"))
{
t.Start();
doc.LoadFamily(path, out var loadedFamily);
if (loadedFamily == null)
{
TaskDialog.Show("Family Not Found", $"Couldn't find: {path}");
return Result.Succeeded;
}
var typeCatalogForm = new TypeCatalog();
typeCatalogForm.ShowDialog();
// Load Selected Symbols
var selectedSymbolNames = typeCatalogForm.Types.Table.Rows
.OfType<DataRow>()
.Where(x => x[0] is bool selected && selected)
.Select(x => x["Type"] as string)
.ToHashSet();
var loadedSymbols = loadedFamily.GetFamilySymbolIds().Select(x => doc.GetElement(x))
.OfType<FamilySymbol>()
.ToList();
// remove any loaded symbols that were not selected
foreach (var symbol in loadedSymbols)
{
if (selectedSymbolNames.Contains(symbol.Name)) continue;
doc.Delete(symbol.Id);
}
t.Commit();
}
return Result.Succeeded;
}
请注意,您可能需要稍微清理一下,因为这只是为了说明如何完成。
public partial class TypeCatalog : Window
{
public DataView Types { get; set; }
public TypeCatalog()
{
Types = CreateDataSource();
InitializeComponent();
DataContext = this;
}
string CSVDataBase = @"c:\StackOverflow\Box.txt";
//Create Collection for DataGrid Source
DataView CreateDataSource()
{
//Create new DataTables and Rows
DataTable dt = new DataTable();
dt.Columns.Add("Selected", typeof(bool));
DataRow dr;
bool firstRow = true;
var lines = File.ReadLines(CSVDataBase);
//For each line in the File
foreach (string Line in lines)
{
var cols = Line.Split(',');
if (firstRow) // first row is the headers
{
bool firstCol = true;
foreach (var col in cols)
{
if (firstCol)
{
firstCol = false;
dt.Columns.Add("Type"); // first column doesn't have a header in the text file
continue;
}
// the headers have a lot of extra stuff we don't care about
string cleanedHeader = col.Split('#')[0].Split('[')[0];
dt.Columns.Add(cleanedHeader);
}
firstRow = false;
continue;
}
//Create new Row
dr = dt.NewRow();
for (var i = 0; i < cols.Length - 1; i++)
{
dr[i+1] = cols[i];
}
dt.Rows.Add(dr);
}
//Return Dataview
DataView dv = new DataView(dt);
return dv;
}
}
<Window x:Class="StackOverflowAnswers.App.TypeCatalog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="TypeCatalog" Height="450" Width="800">
<Grid>
<DataGrid ItemsSource="{Binding Types}" />
</Grid>
</Window>