Revit API にはモードレス ダイアログの使用に適応するための、外部イベント フレームワークが用意されています。これは非同期の処理用に作成されたもので、既定の頻度による Idling イベントと同様に動作します。
外部イベント フレームワークを使用してモードレス ダイアログを実装するには、次の手順を実行します。
これは、外部イベントに対して実装するインタフェースです。このインタフェースを実装するクラスのインスタンスは Revit に登録され、対応する外部イベントが発生するたびに、このインタフェースの Execute メソッドが呼び出されます。
IExternalEventHandler が実装するメソッドは Execute()メソッドと GetName()メソッドの 2 つであり、後者はイベントの名前を返します。次は、イベントの発生時に TaskDialog を表示する、基本的な実装です。
|
コード領域: IExternalEventHandler を実装 |
public class ExternalEventExample : IExternalEventHandler
{
public void Execute(UIApplication app)
{
TaskDialog.Show("External Event", "Click Close to close.");
}
public string GetName()
{
return "External Event Example";
}
}
|
ExternalEvent を作成するには、ExternalEvent クラスを使用します。イベントの作成時には、このクラスのインスタンスが外部イベントの所有者に返されます。イベントの所有者はこのインスタンスを使用して、Revit にイベントの呼び出しの信号を送ります。Revit はイベントの信号が届いていないか(発生していないか)を定期的に確認し、イベントのそれぞれのハンドラで Execute メソッドを呼び出して、発生したすべてのイベントを実行します。
次の例は、ExternalCommand(コード領域の最後に表示)から呼び出されるメソッド ShowForm()を持つ IExternalApplication の実装を表しています。上記の例では、ShowForm()メソッドは外部イベント ハンドラの新しいインスタンスを作成して、新しい ExternalEvent を作成し、その後にモードレス ダイアログ ボックスを表示します。後ほどモードレス ダイアログ ボックスは ExternalEvent オブジェクトで渡される値を使用してイベントを発生させます。
|
コード領域: ExternalEvent を作成 |
public class ExternalEventExampleApp : IExternalApplication
{
// class instance
public static ExternalEventExampleApp thisApp = null;
// ModelessForm instance
private ExternalEventExampleDialog m_MyForm;
public Result OnShutdown(UIControlledApplication application)
{
if (m_MyForm != null && m_MyForm.Visible)
{
m_MyForm.Close();
}
return Result.Succeeded;
}
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;
}
// The external command invokes this on the end-user's request
public void ShowForm(UIApplication uiapp)
{
// If we do not have a dialog yet, create and show it
if (m_MyForm == null || m_MyForm.IsDisposed)
{
// A new handler to handle request posting by the dialog
ExternalEventExample handler = new ExternalEventExample();
// External Event for the dialog to use (to post requests)
ExternalEvent exEvent = ExternalEvent.Create(handler);
// We give the objects to the new dialog;
// The dialog becomes the owner responsible for disposing them, eventually.
m_MyForm = new ExternalEventExampleDialog(exEvent, handler);
m_MyForm.Show();
}
}
}
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class Command : IExternalCommand
{
public virtual Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
try
{
ExternalEventExampleApp.thisApp.ShowForm(commandData.Application);
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
|
モードレス ダイアログが表示されると、ユーザによるやりとりが可能になります。ダイアログでの操作により Revit での何らかの操作のトリガが必要となる場合があります。このような場合、ExternalEvent.Raise()メソッドが呼び出されます。次は、2 つのボタン(イベントを発生させるボタンとダイアログを閉じるボタン)のある簡単なモードレス ダイアログのコード例です。
|
コード領域: イベントを発生 |
public partial class ExternalEventExampleDialog : Form
{
private ExternalEvent m_ExEvent;
private ExternalEventExample m_Handler;
public ExternalEventExampleDialog(ExternalEvent exEvent, ExternalEventExample handler)
{
InitializeComponent();
m_ExEvent = exEvent;
m_Handler = handler;
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
// we own both the event and the handler
// we should dispose it before we are closed
m_ExEvent.Dispose();
m_ExEvent = null;
m_Handler = null;
// do not forget to call the base class
base.OnFormClosed(e);
}
private void closeButton_Click(object sender, EventArgs e)
{
Close();
}
private void showMessageButton_Click(object sender, EventArgs e)
{
m_ExEvent.Raise();
}
}
|
ExternalEvent.Raise()メソッドを呼び出すと、Revit は使用可能な Idling 時間サイクルを待ち、その後 IExternalEventHandler.Execute()メソッドを呼び出します。この簡単な例では、上記の最初のコード領域にあるように、テキスト「Click Close to close.」が記載された TaskDialog が表示されます。
外部イベント フレームワークを使用したより複雑な例については、ModelessDialog¥ModelessForm_ExternalEvent フォルダ内の SDK にあるサンプル コードを参照してください。これは多数のボタンのあるモードレス ダイアログを使用しており、IExternalEventHandler の実装には押されたボタンを追跡するためのパブリック プロパティがあり、Execute()メソッドでその値がオンに切り替わるようになっています。