应用程序:AutoStamp

Revit平台:所有

Revit版本:2011.0

首次发布用于:2010.0

编程语言:C#

技能等级:中等

类别:基础

类型:外部应用

主题:打印视图时自动盖章。

摘要:此示例演示如何订阅ViewPrint事件,在事件处理程序中创建和删除TextNote元素,以及在创建失败时取消事件

相关类:

Autodesk.Revit.UI.IExternalApplication

Autodesk.Revit.DB.TextNote

Autodesk.Revit.DB.Geometry.XYZ

Autodesk.Revit.DB.Events.ViewPrintingEventArgs

Autodesk.Revit.DB.Events.ViewPrintedEventArgs

项目文件:

Application.cs

此文件包含一个类Application,该类实现IExternalApplation接口。当Revit启动时,OnStartUp方法将注册ViewPrinting、ViewPrinted事件。

Eventsactor.cs

这个文件包含一个类Eventsactor,它由两个处理程序方法组成,它们将分别订阅ViewPrinting和ViewPrinted事件;它还包含用于将相关信息转储到日志文件的其他方法。预事件处理程序将在打印开始前创建TextNote元素,并实现自动戳功能;视图打印完成后,后事件处理程序将删除在前事件处理程序中创建的元素。

功能:

该示例实现了IExternalApplication接口,并在OnStartUp方法中订阅ViewPrinting、ViewPrinted、事件;注册的事件处理程序将创建和删除TextNote元素,并在引发事件时将打印相关信息转储到日志文件。

-ControlledApplication级别的ViewPrinting和ViewPrinted事件的事件委托将被订阅以对打印操作作出反应。

-当引发ViewPrinting时,EventAgrs属性View将用作TextNote.Create方法的视图方法参数;处理程序还将保留新创建的TextNote的Id值,以便以后删除它。

-如果由于某种原因创建TextNote失败,此示例将通过将ViewPrinting EventAgrs的cancel属性设置为true来取消此视图的打印过程。

-当引发ViewPrinted时,EventArgs属性Document可用于通过方法Document.delete(ElementId)删除元素。

-方法Autodesk.Revit.DB.TextNote.Create(…)将用于创建TextNote元素。

-可以通过方法PrintSetting.PrinterName从EventAgrs属性Setting中检索打印机名称;可以通过System.Environment.UserName检索用户名。

实施:

1.将示例文件夹下提供的.addin文件复制到Revit的安装文件夹,并指定dll的完整路径。

2.启动Revit,注意ViewPrinting和ViewPrinted事件将自动注册。

3.通过UI引发打印事件:运行打印命令File\print打印视图;每个打印的视图将在视图的原始位置自动加盖打印机名称和用户名(如果AutoStamp.dll是在调试模式下构建的);如果您在发布模式下构建AutoStamp.dll,则将打印“ABC…XYZ”以进行查看。

//注:

该示例设计为在通过Revit的UI调用打印时工作。如果从API调用内部调用打印,则可能无法正常工作,因为API命令可能会对当前文档施加编辑限制。

完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码

Application.cs

//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// 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 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.Text;

using Autodesk.Revit;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;

namespace Revit.SDK.Samples.AutoStamp.CS
{
    /// <summary>
    /// This class implements the methods of interface IExternalApplication and register View Print related events.
    /// OnStartUp method will register ViewPrinting and ViewPrinted events and unregister them in OnShutDown method.
    /// The registered events will help implement the sample functionalities. 
    /// </summary>
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
    [Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
    public class Application : IExternalApplication
    {
        #region Class Member Variable
        /// <summary>
        /// Events reactor for ViewPrint related events
        /// </summary>
        EventsReactor m_eventsReactor;
        #endregion


        #region IExternalApplication Members
        /// <summary>
        /// Implements the OnStartup method to register events when Revit starts.
        /// </summary>
        /// <param name="application">Controlled application of to be loaded to Revit process.</param>
        /// <returns>Return the status of the external application.</returns>
        public Autodesk.Revit.UI.Result OnStartup(UIControlledApplication application)
        {
            // Register related events
            m_eventsReactor = new EventsReactor();
            application.ControlledApplication.ViewPrinting += new EventHandler<Autodesk.Revit.DB.Events.ViewPrintingEventArgs>(m_eventsReactor.AppViewPrinting);
            application.ControlledApplication.ViewPrinted += new EventHandler<Autodesk.Revit.DB.Events.ViewPrintedEventArgs>(m_eventsReactor.AppViewPrinted);
            return Autodesk.Revit.UI.Result.Succeeded;
        }

        /// <summary>
        /// Implements this method to unregister the subscribed events when Revit exits.
        /// </summary>
        /// <param name="application">Controlled application to be shutdown.</param>
        /// <returns>Return the status of the external application.</returns>
        public Autodesk.Revit.UI.Result OnShutdown(UIControlledApplication application)
        {
            // just close log file
            m_eventsReactor.CloseLogFiles();
            //
            // unregister events
            application.ControlledApplication.ViewPrinting -= new EventHandler<Autodesk.Revit.DB.Events.ViewPrintingEventArgs>(m_eventsReactor.AppViewPrinting);
            application.ControlledApplication.ViewPrinted -= new EventHandler<Autodesk.Revit.DB.Events.ViewPrintedEventArgs>(m_eventsReactor.AppViewPrinted);
            return Autodesk.Revit.UI.Result.Succeeded;
        }
        #endregion
    }
}

EventsReactor.cs

//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// 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 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.IO;
using System.Text;
using System.Diagnostics;
using System.Collections.Generic;

using Autodesk.Revit;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.DB;

namespace Revit.SDK.Samples.AutoStamp.CS
{
    /// <summary>
    /// This class consists of two handler methods which will be subscribed to ViewPrinting and ViewPrinted events separately,
    /// The pre-event handler will create TextNote element when event is raised, and the post-event handler will delete it.
    /// Meanwhile, these two handler methods will be used to dump designed information to log file.
    /// 
    /// It contains other methods which are used to dump related information(like events arguments and sequences) 
    /// to log file PrintEventsLog.txt.
    /// </summary>
    public sealed class EventsReactor
    {
        #region Class Member Variables
        /// <summary>
        /// This listener is used to monitor the events raising sequences and arguments of events.
        /// it will be bound to log file PrintEventsLog.txt, it will be added to Trace.Listeners.
        /// 
        /// This log file will only contain information of event raising sequence, event arguments, etc.
        /// This file can be used to check if events work well in different platforms, for example:
        /// By this sample, if user printed something, Revit journal will record all operation of users, 
        /// meanwhile PrintEventsLog.txt will be generated. If user run the journal in other machine, user will get another 
        /// PrintEventsLog.txt, by comparing the two files user can figure out easily if the two prints work equally.
        /// </summary>
        private TextWriterTraceListener m_eventsLog;

        /// <summary>
        /// Current assembly path
        /// </summary>
        String m_assemblyPath;

        /// <summary>
        /// Reserves the id of TextNote created by ViewPrinting and delete it in ViewPrinted event.
        /// </summary>
        Autodesk.Revit.DB.ElementId m_newTextNoteId; 
        #endregion


        #region Class Constructor Method
        /// <summary>
        /// Constructor method, it will only initialize m_assemblyPath.
        /// Notice that this method won't open log files at this time.
        /// </summary>
        public EventsReactor()
        {
            // Get assembly path 
            m_assemblyPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        }

        /// <summary>
        ///  Close log files now
        /// </summary>
        public void CloseLogFiles()
        {
            // Flush trace and close it
            Trace.Flush();
            Trace.Close();
            //
            // Close listeners 
            Trace.Flush();
            if (null != m_eventsLog)
            {
                Trace.Listeners.Remove(m_eventsLog);
                m_eventsLog.Flush();
                m_eventsLog.Close();
            }
        }
        #endregion


        #region Class Handler Methods
        /// <summary>
        /// Handler method for ViewPrinting event.
        /// This method will dump EventArgument information of event firstly and then create TextNote element for this view.
        /// View print will be canceled if TextNote creation failed.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event arguments of ViewPrinting event.</param>
        public void AppViewPrinting(object sender, Autodesk.Revit.DB.Events.ViewPrintingEventArgs e)
        {
            // Setup log file if it still is empty
            if (null == m_eventsLog)
            {
                SetupLogFiles(); 
            } 
            //
            // header information
            Trace.WriteLine(System.Environment.NewLine + "View Print Start: ------------------------");
            //
            // Dump the events arguments
            DumpEventArguments(e);
            //
            // Create TextNote for current view, cancel the event if TextNote creation failed
            bool failureOccured = false; // Reserves whether failure occurred when create TextNote
            try
            {
                String strText = String.Format("Printer Name: {0}{1}User Name: {2}",
                    e.Document.PrintManager.PrinterName, System.Environment.NewLine, System.Environment.UserName);
                //
                // Use non-debug compile symbol to write constant text note
#if !(Debug || DEBUG)
                strText = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
#endif
                using( Transaction eventTransaction = new Transaction(e.Document, "External Tool"))
                {
                    eventTransaction.Start();
                    TextNoteOptions options = new TextNoteOptions();
                    options.HorizontalAlignment = HorizontalTextAlignment.Center;
                    options.TypeId = e.Document.GetDefaultElementTypeId(ElementTypeGroup.TextNoteType);
                    TextNote newTextNote = TextNote.Create(e.Document, e.View.Id, XYZ.Zero, strText, options);
                    eventTransaction.Commit();

                    // Check to see whether TextNote creation succeeded
                    if(null != newTextNote)
                    {
                        Trace.WriteLine("Create TextNote element successfully...");
                        m_newTextNoteId = newTextNote.Id;
                    }
                    else
                    {
                       failureOccured = true;
                    }
                }
            }
            catch (System.Exception ex)
            {
               failureOccured = true;
                Trace.WriteLine("Exception occurred when creating TextNote, print will be canceled, ex: " + ex.Message);
            }
            finally
            {
                // Cancel the TextNote creation when failure occurred, meantime the event is cancellable
               if (failureOccured && e.Cancellable)
                {
                    e.Cancel();  
                }
            }
        }

        /// <summary>
        /// Handler method for ViewPrinted event.
        /// This handler will dump information of printed view firstly and then delete the TextNote created in pre-event handler.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event arguments of ViewPrinted event.</param>
        public void AppViewPrinted(object sender, Autodesk.Revit.DB.Events.ViewPrintedEventArgs e)
        {
            // header information
            Trace.WriteLine(System.Environment.NewLine + "View Print End: -------");
            //
            // Dump the events arguments 
            DumpEventArguments(e);
            //
            // Delete the TextNote element created in ViewPrinting only when view print process succeeded or failed.
            // We don't care about the delete when event status is Cancelled because no TextNote element
            // will be created when cancelling occurred.
            if(RevitAPIEventStatus.Cancelled != e.Status)
            {
               //now event framework will not provide transaction, user need start by self(2009/11/18)
               Transaction eventTransaction = new Transaction(e.Document, "External Tool");
               eventTransaction.Start();
               e.Document.Delete(m_newTextNoteId);
               eventTransaction.Commit();
               Trace.WriteLine("Succeeded to delete the created TextNote element.");
            }
        }               
        #endregion 


        #region Class Implementations
        /// <summary>
        /// For singleton consideration, setup log file only when ViewPrinting is raised.
        /// m_eventsLog will be initialized and added to Trace.Listeners, 
        /// PrintEventsLog.txt will be removed if it already existed.
        /// </summary>
        private void SetupLogFiles()
        {
            // singleton instance for log file
            if (null != m_eventsLog)
            {
                return;
            }
            //
            // delete existed log files
            String printEventsLogFile = Path.Combine(m_assemblyPath, "PrintEventsLog.txt");
            if (File.Exists(printEventsLogFile))
            {
                File.Delete(printEventsLogFile);
            }
            //
            // Create listener and add to Trace.Listeners to monitor the string to be emitted
            m_eventsLog = new TextWriterTraceListener(printEventsLogFile);
            Trace.Listeners.Add(m_eventsLog);
            Trace.AutoFlush = true; // set auto flush to ensure the emitted string can be dumped in time
        }

        /// <summary>
        /// Dump the events arguments to log file PrintEventsLog.txt.
        /// This method will only dump EventArguments of ViewPrint, two event arguments will be handled:
        /// ViewPrintingEventArgs and ViewPrintedEventArgs.
        /// Typical properties of EventArgs of them will be dumped to log file.
        /// </summary>
        /// <param name="eventArgs">Event argument to be dumped. </param>
        private static void DumpEventArguments(RevitAPIEventArgs eventArgs)
        {
            // Dump parameters now:
            // white space is for align purpose.
            if (eventArgs.GetType().Equals(typeof(ViewPrintingEventArgs)))
            {
                Trace.WriteLine("ViewPrintingEventArgs Parameters ------>");
                ViewPrintingEventArgs args = eventArgs as ViewPrintingEventArgs;
                Trace.WriteLine("    TotalViews          : " + args.TotalViews);
                Trace.WriteLine("    View Index          : " + args.Index);
                Trace.WriteLine("    View Information    :"); 
                DumpViewInfo(args.View, "      ");
            }
            else if (eventArgs.GetType().Equals(typeof(ViewPrintedEventArgs)))
            {
                Trace.WriteLine("ViewPrintedEventArgs Parameters ------>");
                ViewPrintedEventArgs args = eventArgs as ViewPrintedEventArgs;
                Trace.WriteLine("    Event Status        : " + args.Status);
                Trace.WriteLine("    TotalViews          : " + args.TotalViews);
                Trace.WriteLine("    View Index          : " + args.Index); 
                Trace.WriteLine("    View Information    :"); 
                DumpViewInfo(args.View, "      ");
            }
            else
            {
                // no handling for other arguments
            }
        }

        /// <summary>
        /// Dump information of  view(View name and type) to log file.
        /// </summary>
        /// <param name="view">View element to be dumped to log files.</param>
        /// <param name="prefix">Prefix mark for each line dumped to log files.</param>
        private static void DumpViewInfo(View view, String prefix)
        {
            Trace.WriteLine(String.Format("{0} ViewName: {1}, ViewType: {2}", 
                prefix, view.Name, view.ViewType));
        }
        #endregion
    }
}