Revit SDK 介绍:PostCommandWorkflow

前言

这个例子介绍的是如何改变 Revit 的保存命令的行为。

内容

程序的步骤:

  1. 启动监测
    Revit SDK 介绍:PostCommandWorkflow_第1张图片
  2. 修改文件,点击保存
    Revit SDK 介绍:PostCommandWorkflow_第2张图片
  3. 选择 Add revision nowRevit SDK 介绍:PostCommandWorkflow_第3张图片
    Revit SDK 介绍:PostCommandWorkflow_第4张图片

程序逻辑

菜单的创建与菜单文字的切换

Revit SDK 介绍:PostCommandWorkflow_第5张图片

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;
}

定义 DocumentSaving 事件行为:
Revit SDK 介绍:PostCommandWorkflow_第6张图片

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);
}

弹出修订对话框:
Revit SDK 介绍:PostCommandWorkflow_第7张图片

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));
}

Notes

  1. Revit 的命令可以自己去触发 uiApp.PostCommand
  2. 命令绑定 application.CreateAddInCommandBinding
  3. 显示Revit对话框的时候有一个可操作时机 uiApp.DialogBoxShowing

你可能感兴趣的:(Revit,SDK,介绍,ui,C#)