应用程序名称:ModelessForm_IdlingEvent
Revit 平台:所有版本
Revit 版本:2013.0
首次发布于:2013.0
编程语言:C#
技能级别:中级
类别:基础
类型:ExternalCommand 和 ExternalApplication
主题:显示无模式窗体(Idling 事件)
摘要:
该示例演示如何利用 Idling 事件从外部无模式对话框与 Revit API 进行通信。
类:
Autodesk.Revit.DB;
Autodesk.Revit.UI;
Autodesk.Revit.UI.Events;
项目文件:
Command.cs
包含从接口 IExternalCommand 继承并实现 Execute 方法的 Command 类。
Application.cs
包含从接口 IExternalApplication 继承并实现其方法的 Command 类。
Request.cs
包含当前请求的变量绑定的类。
RequestHandler.cs
带有执行对话框用户发出的请求的方法的类。
ModelessForm.cs
我们无模式对话框的类。
描述:
该示例演示如何利用 Idling 事件从外部无模式对话框与 Revit API 进行通信。
说明:
1. 启动 Revit 并创建一个新文档。
2. 创建几堵墙,并在其上添加一些门——保留在平面图视图中。
3. 启动 AddIn 命令——“显示无模式窗体(Idling 事件)”。
4. 当对话框出现时,选择一些门。
5. 使用无模式对话框中的命令按钮操纵门。
源代码
完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码
Application.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.Text;
using System.Windows.Forms;
using System.IO;
using Autodesk;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.UI.Events;
namespace Revit.SDK.Samples.ModelessForm_IdlingEvent.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalApplication
/// </summary>
public class Application : IExternalApplication
{
// class instance
internal static Application thisApp = null;
// ModelessForm instance
private ModelessForm m_MyForm;
#region IExternalApplication Members
/// <summary>
/// Implements the OnShutdown event
/// </summary>
/// <param name="application"></param>
/// <returns></returns>
public Result OnShutdown(UIControlledApplication application)
{
if (m_MyForm != null && !m_MyForm.IsDisposed)
{
m_MyForm.Dispose();
m_MyForm = null;
// if we've had a dialog, we had subscribed
application.Idling -= IdlingHandler;
}
return Result.Succeeded;
}
/// <summary>
/// Implements the OnStartup event
/// </summary>
/// <param name="application"></param>
/// <returns></returns>
public Result OnStartup(UIControlledApplication application)
{
m_MyForm = null; // no dialog needed yet; the command will bring it
thisApp = this; // static access to this application instance
return Result.Succeeded;
}
/// <summary>
/// This method creates and shows a modeless dialog, unless it already exists.
/// </summary>
/// <remarks>
/// The external command invokes this on the end-user's request
/// </remarks>
///
public void ShowForm(UIApplication uiapp)
{
// If we do not have a dialog yet, create and show it
if (m_MyForm == null || m_MyForm.IsDisposed)
{
m_MyForm = new ModelessForm();
m_MyForm.Show();
// if we have a dialog, we need Idling too
uiapp.Idling += IdlingHandler;
}
}
/// <summary>
/// A handler for the Idling event.
/// </summary>
/// <remarks>
/// We keep the handler very simple. First we check
/// if we still have the dialog. If not, we unsubscribe from Idling,
/// for we no longer need it and it makes Revit speedier.
/// If we do have the dialog around, we check if it has a request ready
/// and process it accordingly.
/// </remarks>
///
public void IdlingHandler(object sender, IdlingEventArgs args)
{
UIApplication uiapp = sender as UIApplication;
if (m_MyForm.IsDisposed)
{
uiapp.Idling -= IdlingHandler;
return;
}
else // dialog still exists
{
// fetch the request from the dialog
RequestId request = m_MyForm.Request.Take();
if (request != RequestId.None)
{
try
{
// we take the request, if any was made,
// and pass it on to the request executor
RequestHandler.Execute(uiapp, request);
}
finally
{
// The dialog may be in its waiting state;
// make sure we wake it up even if we get an exception.
m_MyForm.WakeUp();
}
}
}
return;
}
#endregion
}
}
Request.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.Threading;
namespace Revit.SDK.Samples.ModelessForm_IdlingEvent.CS
{
/// <summary>
/// A list of requests the dialog has available
/// </summary>
///
public enum RequestId : int
{
/// <summary>
/// None
/// </summary>
None = 0,
/// <summary>
/// "Delete" request
/// </summary>
Delete = 1,
/// <summary>
/// "FlipLeftRight" request
/// </summary>
FlipLeftRight = 2,
/// <summary>
/// "FlipInOut" request
/// </summary>
FlipInOut = 3,
/// <summary>
/// "MakeRight" request
/// </summary>
MakeRight = 4,
/// <summary>
/// "MakeLeft" request
/// </summary>
MakeLeft = 5,
/// <summary>
/// "TurnOut" request
/// </summary>
TurnOut = 6,
/// <summary>
/// "TurnIn" request
/// </summary>
TurnIn = 7,
/// <summary>
/// "Rotate" request
/// </summary>
Rotate = 8
}
/// <summary>
/// A class around a variable holding the current request.
/// </summary>
/// <remarks>
/// Access to it is made thread-safe, even though we don't necessarily
/// need it if we always disable the dialog between individual requests.
/// </remarks>
///
public class Request
{
// Storing the value as a plain Int makes using the interlocking mechanism simpler
private int m_request = (int)RequestId.None;
/// <summary>
/// Take - The Idling handler calls this to obtain the latest request.
/// </summary>
/// <remarks>
/// This is not a getter! It takes the request and replaces it
/// with 'None' to indicate that the request has been "passed on".
/// </remarks>
///
public RequestId Take()
{
return (RequestId)Interlocked.Exchange(ref m_request, (int)RequestId.None);
}
/// <summary>
/// Make - The Dialog calls this when the user presses a command button there.
/// </summary>
/// <remarks>
/// It replaces any older request previously made.
/// </remarks>
///
public void Make(RequestId request)
{
Interlocked.Exchange(ref m_request, (int)request);
}
}
}
RequestHandler.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.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace Revit.SDK.Samples.ModelessForm_IdlingEvent.CS
{
/// <summary>
/// A class with methods to execute requests made by the dialog user.
/// </summary>
///
public static class RequestHandler
{
// A trivial delegate, but handy
private delegate void DoorOperation(FamilyInstance e);
/// <summary>
/// The top function that distributes requests to individual methods.
/// </summary>
///
public static void Execute(UIApplication uiapp, RequestId reqest)
{
switch (reqest)
{
case RequestId.None:
{
return; // no request at this time -> we can leave immediately
}
case RequestId.Delete:
{
ModifySelectedDoors(uiapp, "Delete doors", e => e.Document.Delete(e.Id));
break;
}
case RequestId.FlipLeftRight:
{
ModifySelectedDoors(uiapp, "Flip door Hand", e => e.flipHand());
break;
}
case RequestId.FlipInOut:
{
ModifySelectedDoors(uiapp, "Flip door Facing", e => e.flipFacing());
break;
}
case RequestId.MakeLeft:
{
ModifySelectedDoors(uiapp, "Make door Left", MakeLeft);
break;
}
case RequestId.MakeRight:
{
ModifySelectedDoors(uiapp, "Make door Right", MakeRight);
break;
}
case RequestId.TurnOut:
{
ModifySelectedDoors(uiapp, "Place door Out", TurnOut);
break;
}
case RequestId.TurnIn:
{
ModifySelectedDoors(uiapp, "Place door In", TurnIn);
break;
}
case RequestId.Rotate:
{
ModifySelectedDoors(uiapp, "Rotate door", FlipHandAndFace);
break;
}
default:
{
// some kind of a warning here should
// notify us about an unexpected request
break;
}
}
return;
}
/// <summary>
/// The main door-modification subroutine - called from every request
/// </summary>
/// <remarks>
/// It searches the current selection for all doors
/// and if it finds any it applies the requested operation to them
/// </remarks>
/// <param name="uiapp">The Revit application object</param>
/// <param name="text">Caption of the transaction for the operation.</param>
/// <param name="operation">A delegate to perform the operation on an instance of a door.</param>
///
private static void ModifySelectedDoors(UIApplication uiapp, String text, DoorOperation operation)
{
UIDocument uidoc = uiapp.ActiveUIDocument;
// check if there is anything selected in the active document
if ((uidoc != null) && (uidoc.Selection != null))
{
ICollection<ElementId> selElements = uidoc.Selection.GetElementIds();
if (selElements.Count > 0)
{
// Filter out all doors from the current selection
FilteredElementCollector collector = new FilteredElementCollector(uidoc.Document, selElements);
ICollection<Element> doorset = collector.OfCategory(BuiltInCategory.OST_Doors).ToElements();
if (doorset != null)
{
// Since we'll modify the document, we need a transaction
// It's best if a transaction is scoped by a 'using' block
using (Transaction trans = new Transaction(uidoc.Document))
{
// The name of the transaction was given as an argument
if (trans.Start(text) == TransactionStatus.Started)
{
// apply the requested operation to every door
foreach (FamilyInstance door in doorset)
{
operation(door);
}
trans.Commit();
}
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////
//
// Helpers - simple delegates operating upon an instance of a door
private static void FlipHandAndFace(FamilyInstance e)
{
e.flipFacing(); e.flipHand();
}
// Note: The door orientation [left/right] is according the common
// conventions used by the building industry in the Czech Republic.
// If the convention is different in your county (like in the U.S),
// swap the code of the MakeRight and MakeLeft methods.
private static void MakeLeft(FamilyInstance e)
{
if (e.FacingFlipped ^ e.HandFlipped) e.flipHand();
}
private static void MakeRight(FamilyInstance e)
{
if (!(e.FacingFlipped ^ e.HandFlipped)) e.flipHand();
}
// Note: The In|Out orientation depends on the position of the
// wall the door is in; therefore it does not necessary indicates
// the door is facing Inside, or Outside, respectively.
// The presented implementation is good enough to demonstrate
// how to flip a door, but the actual algorithm will likely
// have to be changes in a read-world application.
private static void TurnIn(FamilyInstance e)
{
if (!e.FacingFlipped) e.flipFacing();
}
private static void TurnOut(FamilyInstance e)
{
if (e.FacingFlipped) e.flipFacing();
}
} // class
} // namespace
ModelessForm.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.
//
namespace Revit.SDK.Samples.ModelessForm_IdlingEvent.CS
{
partial class ModelessForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnExit = new System.Windows.Forms.Button();
this.btnDeleted = new System.Windows.Forms.Button();
this.btnFlipUpDown = new System.Windows.Forms.Button();
this.btnFlipLeftRight = new System.Windows.Forms.Button();
this.btnFlipLeft = new System.Windows.Forms.Button();
this.btnFlipRight = new System.Windows.Forms.Button();
this.btnFlipUp = new System.Windows.Forms.Button();
this.btnFlipDown = new System.Windows.Forms.Button();
this.btnRotate = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnExit
//
this.btnExit.Location = new System.Drawing.Point(66, 146);
this.btnExit.Name = "btnExit";
this.btnExit.Size = new System.Drawing.Size(89, 23);
this.btnExit.TabIndex = 0;
this.btnExit.Text = "Exit";
this.btnExit.UseVisualStyleBackColor = true;
this.btnExit.Click += new System.EventHandler(this.btnExit_Click);
//
// btnDeleted
//
this.btnDeleted.Location = new System.Drawing.Point(115, 102);
this.btnDeleted.Name = "btnDeleted";
this.btnDeleted.Size = new System.Drawing.Size(89, 24);
this.btnDeleted.TabIndex = 8;
this.btnDeleted.Text = "Delete";
this.btnDeleted.UseVisualStyleBackColor = true;
this.btnDeleted.Click += new System.EventHandler(this.btnDelete_Click);
//
// btnFlipUpDown
//
this.btnFlipUpDown.Location = new System.Drawing.Point(115, 12);
this.btnFlipUpDown.Name = "btnFlipUpDown";
this.btnFlipUpDown.Size = new System.Drawing.Size(89, 24);
this.btnFlipUpDown.TabIndex = 2;
this.btnFlipUpDown.Text = "In / Out";
this.btnFlipUpDown.UseVisualStyleBackColor = true;
this.btnFlipUpDown.Click += new System.EventHandler(this.btnFlipInOut_Click);
//
// btnFlipLeftRight
//
this.btnFlipLeftRight.Location = new System.Drawing.Point(12, 12);
this.btnFlipLeftRight.Name = "btnFlipLeftRight";
this.btnFlipLeftRight.Size = new System.Drawing.Size(89, 24);
this.btnFlipLeftRight.TabIndex = 1;
this.btnFlipLeftRight.Text = "Left / Right";
this.btnFlipLeftRight.UseVisualStyleBackColor = true;
this.btnFlipLeftRight.Click += new System.EventHandler(this.btnFlipLeftRight_Click);
//
// btnFlipLeft
//
this.btnFlipLeft.Location = new System.Drawing.Point(12, 42);
this.btnFlipLeft.Name = "btnFlipLeft";
this.btnFlipLeft.Size = new System.Drawing.Size(89, 24);
this.btnFlipLeft.TabIndex = 3;
this.btnFlipLeft.Text = "Left";
this.btnFlipLeft.UseVisualStyleBackColor = true;
this.btnFlipLeft.Click += new System.EventHandler(this.btnFlipLeft_Click);
//
// btnFlipRight
//
this.btnFlipRight.Location = new System.Drawing.Point(12, 72);
this.btnFlipRight.Name = "btnFlipRight";
this.btnFlipRight.Size = new System.Drawing.Size(89, 24);
this.btnFlipRight.TabIndex = 5;
this.btnFlipRight.Text = "Right";
this.btnFlipRight.UseVisualStyleBackColor = true;
this.btnFlipRight.Click += new System.EventHandler(this.btnFlipRight_Click);
//
// btnFlipUp
//
this.btnFlipUp.Location = new System.Drawing.Point(115, 42);
this.btnFlipUp.Name = "btnFlipUp";
this.btnFlipUp.Size = new System.Drawing.Size(89, 24);
this.btnFlipUp.TabIndex = 4;
this.btnFlipUp.Text = "Out";
this.btnFlipUp.UseVisualStyleBackColor = true;
this.btnFlipUp.Click += new System.EventHandler(this.btnFlipOut_Click);
//
// btnFlipDown
//
this.btnFlipDown.Location = new System.Drawing.Point(115, 72);
this.btnFlipDown.Name = "btnFlipDown";
this.btnFlipDown.Size = new System.Drawing.Size(89, 24);
this.btnFlipDown.TabIndex = 6;
this.btnFlipDown.Text = "In";
this.btnFlipDown.UseVisualStyleBackColor = true;
this.btnFlipDown.Click += new System.EventHandler(this.btnFlipIn_Click);
//
// btnRotate
//
this.btnRotate.Location = new System.Drawing.Point(12, 102);
this.btnRotate.Name = "btnRotate";
this.btnRotate.Size = new System.Drawing.Size(89, 24);
this.btnRotate.TabIndex = 7;
this.btnRotate.Text = "Rotate";
this.btnRotate.UseVisualStyleBackColor = true;
this.btnRotate.Click += new System.EventHandler(this.btnRotate_Click);
//
// ModelessForm
//
this.AcceptButton = this.btnExit;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(216, 184);
this.Controls.Add(this.btnRotate);
this.Controls.Add(this.btnFlipRight);
this.Controls.Add(this.btnFlipLeft);
this.Controls.Add(this.btnFlipLeftRight);
this.Controls.Add(this.btnFlipDown);
this.Controls.Add(this.btnFlipUp);
this.Controls.Add(this.btnFlipUpDown);
this.Controls.Add(this.btnDeleted);
this.Controls.Add(this.btnExit);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "ModelessForm";
this.Opacity = 0.75D;
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Door Operator (Idling Event)";
this.TopMost = true;
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button btnExit;
private System.Windows.Forms.Button btnDeleted;
private System.Windows.Forms.Button btnFlipUpDown;
private System.Windows.Forms.Button btnFlipLeftRight;
private System.Windows.Forms.Button btnFlipLeft;
private System.Windows.Forms.Button btnFlipRight;
private System.Windows.Forms.Button btnFlipUp;
private System.Windows.Forms.Button btnFlipDown;
private System.Windows.Forms.Button btnRotate;
}
}
版权所有 :无锡模信建筑科技有限公司 苏ICP备2021028830号-1 BIM建模|BIM技术应用|BIM软件开发
联系地址:江苏省无锡市新吴区龙山路4号B座705 手机:18761516598