这个例子介绍的是如何改变 Revit 的保存命令的行为。
程序的步骤:
在IExternalApplication
中创建菜单,并将按钮传给 PostCommandRevisionMonitorCommand
,方便后续文字的修改。
namespace Revit.SDK.Samples.PostCommandWorkflow.CS
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class Application : IExternalApplication
{
public Result OnStartup(UIControlledApplication application)
{
CreateUIPanel(application);
return Result.Succeeded;
}
/// 在 addin 面板上创建菜单
private void CreateUIPanel(UIControlledApplication application)
{
RibbonPanel rp = application.CreateRibbonPanel("UI");
PushButtonData setupMonitor = new PushButtonData("Setup_Revision_Monitor", "Setup Revision Monitor",
addAssemblyPath,
typeof(Revit.SDK.Samples.PostCommandWorkflow.CS.PostCommandRevisionMonitorCommand).FullName);
PushButton setupMonitorPB = rp.AddItem(setupMonitor) as PushButton;
SetIconsForPushButton(setupMonitorPB, Revit.SDK.Samples.PostCommandWorkflow.CS.Properties.Resources.RevisionIcon);
// 把 setupMonitorPB 传给 PostCommandRevisionMonitorCommand,方便后续切换文字
PostCommandRevisionMonitorCommand.SetPushButton(setupMonitorPB);
}
}
}
文字切换的逻辑:
// PostCommandRevisionMonitorCommand
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
Document doc = commandData.Application.ActiveUIDocument.Document;
if (monitor == null)
{
monitor = new PostCommandRevisionMonitor(doc);
monitor.Activate();
commandButton.ItemText = "Remove Revision Monitor";
}
else
{
monitor.Deactivate();
monitor = null;
commandButton.ItemText = "Setup Revision Monitor";
}
return Result.Succeeded;
}
从上面的 PostCommandRevisionMonitorCommand.Execute
可知,第一次启动命令,打开监测:
monitor = new PostCommandRevisionMonitor(doc);
monitor.Activate();
commandButton.ItemText = "Remove Revision Monitor";
注册 DocumentSaving
事件:
public void Activate()
{
// 保存修订的次数,用于后续的判断
storedRevisionCount = GetRevisionCount(document);
// 注册事件
document.DocumentSaving += OnSavingPromptForRevisions;
}
private void OnSavingPromptForRevisions(object sender, DocumentSavingEventArgs args)
{
Document doc = (Document)sender;
UIApplication uiApp = new UIDocument(doc).Application;
// 如果文件被修改了
if (doc.IsModified)
{
// 判断修订的次数和保存的修订次数的差异
int revisionCount = GetRevisionCount(doc);
if (revisionCount <= storedRevisionCount)
{
// 显示上图的对话框
TaskDialog td = new TaskDialog("Revisions not created.");
td.MainIcon = TaskDialogIcon.TaskDialogIconWarning;
td.MainInstruction = "Changes have been made to this document, but no new revision has been created.";
td.ExpandedContent = "Because the document has been released, it is typically required to issue a new " +
"revision number with any change.";
td.AddCommandLink(TaskDialogCommandLinkId.CommandLink1, "Add revision now");
td.AddCommandLink(TaskDialogCommandLinkId.CommandLink2, "Cancel save");
td.AddCommandLink(TaskDialogCommandLinkId.CommandLink3, "Proceed with save (not recommended).");
td.TitleAutoPrefix = false;
td.AllowCancellation = false;
TaskDialogResult result = td.Show();
switch (result)
{
case TaskDialogResult.CommandLink1: // Add revision now
{
// 如果选择 Add revision now,则取消保存,隐藏默认的"Document not saved" 对话框,弹出修订对话框
args.Cancel();
uiApp.DialogBoxShowing += HideDocumentNotSaved;
PromptToEditRevisionsAndResave(uiApp);
break;
}
case TaskDialogResult.CommandLink2: // Cancel save
{
// cancel saving only
args.Cancel();
break;
}
case TaskDialogResult.CommandLink3: // Proceed with save
{
// do nothing
break;
}
}
}
else
{
storedRevisionCount = revisionCount;
}
}
}
隐藏默认的文件未保存对话框,uiApp.DialogBoxShowing += HideDocumentNotSaved
:
private void HideDocumentNotSaved(object sender, DialogBoxShowingEventArgs args)
{
TaskDialogShowingEventArgs tdArgs = args as TaskDialogShowingEventArgs;
// "Document not saved" 对话框,Revit 没有提供一个对应的 id,这里直接通过查找文本来查找。
if (tdArgs != null && tdArgs.Message.Contains("not saved"))
args.OverrideResult(0x0008);
}
private void PromptToEditRevisionsAndResave(UIApplication application)
{
// 设置外部事件,在 ReactToRevisionsAndSchedulesCommand 中被触发。
externalEvent = ExternalEvent.Create(new PostCommandRevisionMonitorEvent(this));
// 查找和绑定命令,设置命令触发前事件
RevitCommandId id = RevitCommandId.LookupPostableCommandId(PostableCommand.SheetIssuesOrRevisions);
if (binding == null)
{
binding = application.CreateAddInCommandBinding(id);
}
binding.BeforeExecuted += ReactToRevisionsAndSchedulesCommand;
// Post the revision editing command
application.PostCommand(id);
}
设置修订命令被执行之后的一系列动作:
/// 设置修订命令被执行之后的一系列动作
private void ReactToRevisionsAndSchedulesCommand(object sender, BeforeExecutedEventArgs args)
{
if (externalEvent != null)
externalEvent.Raise();
}
// PostCommandRevisionMonitorEvent : IExternalEventHandler
public void Execute(UIApplication app)
{
monitor.CleanupAfterRevisionEdit(app);
}
// class PostCommandRevisionMonitor
private void CleanupAfterRevisionEdit(UIApplication uiApp)
{
// Remove dialog box showing
uiApp.DialogBoxShowing -= HideDocumentNotSaved;
if (binding != null)
binding.BeforeExecuted -= ReactToRevisionsAndSchedulesCommand;
externalEvent = null;
// Repost the save command,保存文件
uiApp.PostCommand(RevitCommandId.LookupPostableCommandId(PostableCommand.Save));
}
uiApp.PostCommand
application.CreateAddInCommandBinding
uiApp.DialogBoxShowing