主题:演示如何使用 PostCommand() 推动用户工作流程
摘要:使用 PostCommand() 作为自定义工作流程的一部分。当文档没有添加新的修订版本时,在保存之前提示添加一个。
项目文件:
·Application.cs - 实现 Revit 插件接口 IExternalApplication
·PostCommandRevisionMonitorCommand.cs - 设置修订监视器并执行与之相关的任务的外部命令。
·PostCommandRevisionMonitor.cs - 此类具有在文档保存时提示用户
描述:
此示例演示了如何使用 PostCommand() 方法和各种事件来推动用户工作流程。在此示例中,需要的行为是在保存文档之前让用户创建一个新的修订版本。如果没有添加新的修订版本,则会阻止保存,并自动将用户输入到“工作表/修订版编辑”命令中。完成添加修订之后,外部事件会再次发布保存命令。
事件和活动的工作流如下:
·用户尝试保存
·调用 BeforeSaving 事件
·提示用户缺少新的修订版本的消息
·设置 TaskDialogShowing 事件
·设置 ExternalEvent
·取消 BeforeSaving
·调用 TaskDialogShowing 事件
·关闭有关文档未保存的 TaskDialog
·发布问题工作表/修订版(PostCommand())
·在此命令的 BeforeExecuting 事件中,引发 ExternalEvent(在命令结束后立即回调)
·用户添加新的修订版本并关闭对话框
·调用 IExternalEventHandler
·删除不需要的事件发布保存命令(PostCommand())。
·保存结束
说明:
打开 Revit 和任何可编辑项目。
1.点击“添加-ins->UI->设置修订版本监视器”按钮。
2.对项目进行任何编辑(除了添加新的修订版本)
3.点击保存命令。
4.注意有关需要新修订版本的任务对话框弹出。
5.选择添加修订版本
6.注意发布的问题工作表/修订版
7.添加新的修订版本。
8.关闭对话框。
9.确认现在已进行保存。
10.点击“添加-ins->UI->删除修订版本监视器”按钮以停用监视器。
完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码
PostCommandRevisionMonitor.cs
//
// (C) Copyright 2003-2019 by Autodesk, Inc. All rights reserved.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM 'AS IS' AND WITH ALL ITS FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.UI.Events;
namespace Revit.SDK.Samples.PostCommandWorkflow.CS
{
/// <summary>
/// This class has the capabilities to monitor when a document is saved, and prompt the user to
/// add a revision before save takes place.
/// </summary>
class PostCommandRevisionMonitor
{
/// <summary>
/// Constructs a new revision monitor for the given document.
/// </summary>
/// <param name="doc">The document.</param>
public PostCommandRevisionMonitor(Document doc)
{
document = doc;
}
/// <summary>
/// Activates the revision monitor for the stored document.
/// </summary>
public void Activate()
{
// Save the number of revisions as an initial count.
storedRevisionCount = GetRevisionCount(document);
// Setup event for saving.
document.DocumentSaving += OnSavingPromptForRevisions;
}
/// <summary>
/// Deactivates the revision monitor for the stored document.
/// </summary>
public void Deactivate()
{
// Remove the event for saving.
document.DocumentSaving -= OnSavingPromptForRevisions;
}
#region RevitAPI event callbacks
/// <summary>
/// The DocumentSaving callback. This callback checks if at least one new revision has been added, and if not
/// shows instructions to the user to deal with the situation.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void OnSavingPromptForRevisions(object sender, DocumentSavingEventArgs args)
{
Document doc = (Document)sender;
UIApplication uiApp = new UIDocument(doc).Application;
if (doc.IsModified)
{
// Compare number of revisions with saved count
int revisionCount = GetRevisionCount(doc);
if (revisionCount <= storedRevisionCount)
{
// Show dialog with explanation and options
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
{
// cancel first save
args.Cancel();
// add event to hide the default "Document not saved" dialog
uiApp.DialogBoxShowing += HideDocumentNotSaved;
// post command for editing revisions
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;
}
}
}
/// <summary>
/// The DialogBoxShowing callback to cancel display of the "Document not saved" message when saving is cancelled.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void HideDocumentNotSaved(object sender, DialogBoxShowingEventArgs args)
{
TaskDialogShowingEventArgs tdArgs = args as TaskDialogShowingEventArgs;
// The "Document not saved" dialog does not have a usable id, so we are forced to look at the text instead.
if (tdArgs != null && tdArgs.Message.Contains("not saved"))
args.OverrideResult(0x0008);
}
/// <summary>
/// The BeforeExecuted callback for the command, to setup the post action after the revision command is run.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void ReactToRevisionsAndSchedulesCommand(object sender, BeforeExecutedEventArgs args)
{
if (externalEvent != null)
externalEvent.Raise();
}
/// <summary>
/// The external event raised to finalize the workflow after the user has been prompted to enter the
/// Sheet Revisions/Issues command.
/// </summary>
class PostCommandRevisionMonitorEvent : IExternalEventHandler
{
#region IExternalEventHandler Members
/// <summary>
/// The external event callback to finalize the workflow.
/// </summary>
/// <param name="app"></param>
public void Execute(UIApplication app)
{
monitor.CleanupAfterRevisionEdit(app);
}
/// <summary>
/// The external event name.
/// </summary>
/// <returns></returns>
public string GetName()
{
return "PostCommandRevisionMonitorEvent";
}
/// <summary>
/// The constructor for the event instance.
/// </summary>
/// <param name="monitor">The instance of the command.</param>
public PostCommandRevisionMonitorEvent(PostCommandRevisionMonitor monitor)
{
this.monitor = monitor;
}
/// <summary>
/// Handle to the revision monitor.
/// </summary>
private PostCommandRevisionMonitor monitor;
#endregion
}
#endregion
/// <summary>
/// Prompts to edit the revision and resave.
/// </summary>
/// <param name="application"></param>
private void PromptToEditRevisionsAndResave(UIApplication application)
{
// Setup external event to be notified when activity is done
externalEvent = ExternalEvent.Create(new PostCommandRevisionMonitorEvent(this));
// Setup event to be notified when revisions command starts (this is a good place to raise this external event)
RevitCommandId id = RevitCommandId.LookupPostableCommandId(PostableCommand.SheetIssuesOrRevisions);
if (binding == null)
{
binding = application.CreateAddInCommandBinding(id);
}
binding.BeforeExecuted += ReactToRevisionsAndSchedulesCommand;
// Post the revision editing command
application.PostCommand(id);
}
/// <summary>
/// The function that is called to finish the execution of the workflow. Cleans up subscribed events,
/// and posts the save command.
/// </summary>
/// <param name="uiApp"></param>
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));
}
/// <summary>
/// Storage to remember the number of revisions when last checked.
/// </summary>
private int storedRevisionCount = 0;
/// <summary>
/// The handle to the external event instance to be invoked after the revision editing completes.
/// </summary>
private Autodesk.Revit.UI.ExternalEvent externalEvent = null;
/// <summary>
/// The binding to the revision command.
/// </summary>
private AddInCommandBinding binding = null;
/// <summary>
/// The document.
/// </summary>
private Document document;
/// <summary>
/// Counts the number of revision elements in the document.
/// </summary>
/// <param name="doc">The document.</param>
/// <returns>The number of elements found.</returns>
private static int GetRevisionCount(Document doc)
{
// Find revision objects
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.OfCategory(BuiltInCategory.OST_Revisions);
return collector.ToElementIds().Count;
}
}
}
PostCommandRevisionMonitorCommand.cs
版权所有 :无锡模信建筑科技有限公司 苏ICP备2021028830号-1 BIM建模|BIM技术应用|BIM软件开发
联系地址:江苏省无锡市新吴区龙山路4号B座705 手机:18761516598