Building Coder(Revit二次開発)-ドラッグアンドドロップAPI

3826 ワード

原文リンク:Drag and Drop API
Revit 2012のドラッグアンドドロップ動作について議論しています
(drag and drop in Revit 2012)では、外部プロセスから標準のRevitドラッグアンドドロップ動作をトリガーする方法を示します.ただし、Revitがドラッグアンドドロップファイルを受信するデフォルトの動作は変更できません.良いニュースはRevit 2013で私たちはそうすることができます.
Revit 2013 SDKのルーチンUIAPIは、アプリケーションの可用性、プレビューコントロール、カスタムWPFオプションダイアログボックスなど、最新のドラッグ&ドロップAPIおよびプラグイン統合機能を示しています.次の点に注意してください.
1.UIAPIはExternal Applicationなので、RvtSamplesでロードできません
2.UIAPIがRevit 2013 SDKドキュメントに表示されない
UIAPIドラッグ&ドロップコマンドには、以下のモードレスダイアログボックスが表示されます.
左側のListViewにはロードされたファミリーが表示され、右側のListViewには使用可能なすべてのファミリーが表示されます.
UIApplication DoDragDropメソッド
1. DoDragDrop ( ICollection )
複数のファイルを含むドラッグアンドドロップ操作を1回トリガー
2. DoDragDrop ( object, IDropHandler )
カスタマイズ可能なRevit受信動作のドラッグ&ドロップ操作をトリガー
ApplicationEntryPointクラスでも同様の方法が提供されていますが、Revitマクロのみです.
複数のファイルをドラッグ&ドロップ
DoDragDropメソッドの最初のリロード操作のオブジェクトはファイルのセットであり、特定のRevit受信動作をもたらします(少なくとも現在のバージョンではこれらのデフォルト動作は変更できません).
  • CAD形式またはピクチャ形式のファイルのみがドラッグアンドドロップされると、Revitは新しいインポート訪問エディタをポップアップしてファイルインポート
  • を処理する.
  • 複数のCAD形式またはピクチャ形式のファイルがドラッグアンドドロップされると、Revitは、ファイルインポート
  • を処理するために、最初の形式に対して新しいインポート訪問エディタをポップアップするだけである.
  • ファミリーファイルが1つだけドラッグアンドドロップされている場合、Revitはそのファミリーをロードし、エディタをポップアップしてファミリーインスタンス
  • を訪問します.
  • 複数のファミリファイルがドラッグアンドドロップされると、Revitはすべてのファミリ
  • をロードします.
  • 複数のファミリファイルに別の形式のファイルをドラッグ&ドロップすると、Revitはすべてのファイルを開こうとします(注:ファミリはロードされません)
  • .
  • 有効ファイルまたは有効ファイルのセットがドラッグ&ドロップされた場合、Revitはそれらを適切に使用しようとします.ファイルが使用できない場合、Revitは失敗メッセージをポップアップしますが、例外は放出されず、プラグイン
  • にも通知されません.
      private void listBox1_MouseMove( object sender, MouseEventArgs e )
      {
        if( System.Windows.Forms.Control.MouseButtons == MouseButtons.Left )
        {
          FamilyListBoxMember member = (FamilyListBoxMember) listBox1.SelectedItem;
     
          //       Revit     
          List<String> data = new List<String>();
          data.Add( member.FullPath );
          UIApplication.DoDragDrop( data );
        }
      }

    モードレスダイアログからRevit APIを呼び出す欠点
    なお、UIApplicationは、モードレスダイアログから呼び出す.DoDragDropは、非Revit APIコンテキストでRevit APIを呼び出すことを意味する.ほとんどの場合、これは不法であり、予測できない結果を招く可能性があります.したがって、通常、Revit APIは、IdlingイベントまたはExternalイベントのコールバック関数から呼び出されるべきである.しかし、ドラッグアンドドロップ操作では、デッドロックが発生する可能性があります.
    なぜなら、RevitがトリガしたIdlingイベントとExternalイベントは、ユーザーインタフェース操作がないと仮定しているからです.イベントコールバックでトリガUI操作を呼び出すと、次のような状況になる可能性があります.
    1.UI要求は、同じメッセージキューに送信される.ただし、メッセージキューはIdling/Externalイベントの返信を待っているため、この新しいUIリクエストは永遠に処理されません.
    2.UI要求は別のメッセージキューに送信され、この異なるメッセージキューは最終的に新しいIdling/Externalイベントをトリガーし、ユーザーインタフェースのデッドロックを引き起こす
    したがって、結論は失望させ、モードレスダイアログボックスからドラッグアンドドロップ操作を呼び出す安全な方法はありません.
    Revit処理のドラッグ&ドロップのカスタマイズ
    DoDragDrapの2番目のリロードは感動的な新しい特性です.Revitがドラッグアンドドロップファイルを受信する動作を定義できます.IDropHandlerインタフェースを実装し,そのExecute()メソッドで所望の挙動を定義する必要がある.次の例では、IDropHanlderはファミリータイプのElementIdを受信し、P r o m p t ForFamilyInstancePlacement()メソッドを呼び出してユーザーに訪問するように要求します.明らかに、IDropHanlderにカスタマイズされたデータを渡して、ニーズを実現することができます.
      public class LoadedFamilyDropHandler : IDropHandler
      {
        public void Execute( UIDocument doc, object data )
        {
          ElementId familySymbolId = (ElementId) data;
     
          FamilySymbol symbol = doc.Document.GetElement( familySymbolId ) as FamilySymbol;
     
          if( symbol != null )
          {
            doc.PromptForFamilyInstancePlacement( symbol );
          }
        }
      }
    
      private void listView_MouseMove( object sender, MouseEventArgs e )
      {
        if( System.Windows.Forms.Control.MouseButtons == MouseButtons.Left )
        {
          ListViewItem selectedItem = this.listView1.SelectedItems.Cast<ListViewItem>().FirstOrDefault<ListViewItem>();
     
          if( selectedItem != null )
          {
             LoadedFamilyDropHandler myhandler = new LoadedFamilyDropHandler();
             UIApplication.DoDragDrop( selectedItem.Tag, myhandler );
          }
        }
      }