はじめに
AMDlab BIMエンジニアの河野(twitter@tatsukikouno)です。
RevitAPIで学ぶC#シリーズ、第3弾です。
前々回、前回と、Revitのデータ構造に着目した内容でした。
今回からは実際にコードを書いて、RevitアドインからUIを立ち上げてみます。
UIが書けるとアドイン開発の幅がグッと広がると思います。
UIのフレームワークにはWPFを使用し、MVVMパターンで書いていきます。
MVVM(Model-View-ViewModel)は、コードの保守性と再利用性を向上させるための設計パターンです。
細かい部分まで知る必要はないので、こうやって書くんだな!くらいの感覚で大丈夫です。
プロジェクトの作成
「クラスライブラリ(.NET Framework)」でプロジェクトを作成してください。
私はVisual Studio 2022を利用しています。
パッケージの追加
RevitAPIを利用するためのパッケージを追加します。
開発したいRevitバージョンを選択してインストールしてください。
Viewの作成
View、つまりはUIを作成します。
.xaml
ファイルと.xaml.cs
ファイルが追加されます。
.xaml
は、XML形式とC#をつなげて書けるマークアップ言語です。
UI部分をXMLで、ロジック部分をC#で書こう!という魂胆です。
UserControl
はWindow
に、Grid
はStackPanel
に変更しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 |
<Window x:Class="RevitAddinTemplate.MainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:RevitAddinTemplate" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <StackPanel> </StackPanel> </Window> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
using System.Windows; namespace RevitAddinTemplate { /// <summary> /// MainView.xaml の相互作用ロジック /// </summary> public partial class MainView : Window { public MainView() { InitializeComponent(); } } } |
ViewModelの作成
ViewModelを作成します。
ViewはUIでした。Modelはロジックのことです。
ViewModelは、UIとロジックを繋げる存在です。
UIと連動する変数等をまとめて置いておくクラスだと思っておくとよいでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
using Autodesk.Revit.DB; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; namespace RevitAddinTemplate { public class MainViewModel : INotifyPropertyChanged { private int elementsCount; public int ElementsCount { get { return elementsCount; } set { elementsCount = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string name = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } } } |
MainViewModel
クラスには、INotifyPropertyChanged
インターフェイスとOnPropertyChanged
メソッドを実装します。
これらはViewModelの変更をViewに通知するための実装です。
仕組みが気になる方は調べてみてください。
その他の部分について解説します。
今回は、RVTドキュメント内のElement
の個数を数えてUIに表示するアドインを作成します。
「RVTドキュメント内のElementの個数」を格納するフィールドが以下の行です
1 |
private int elementsCount; |
private
なフィールドなので、MainViewModel
クラス以外からはアクセスできません。
そこで、フィールドへのアクセスを提供するのが以下のElementsCount
プロパティになります。
1 2 3 4 5 6 7 8 9 |
public int ElementsCount { get { return elementsCount; } set { elementsCount = value; OnPropertyChanged(); } } |
ElementsCount
は、Get
時はフィールドの値を返すだけですが、Set
時はフィールドへの値セットに加えてOnPropertyChanged()が呼ばれます。
private
なフィールドとプロパティ(Getter,Setter)を組み合わせることで、値を設定・取得するときの処理を保証できます。
ViewにViewModelをバインドする
まずはMainView.xaml.cs
を書き換え、DataContext
にMainViewModel
オブジェクトが渡されるようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using System.Windows; namespace RevitAddinTemplate { /// <summary> /// MainView.xaml の相互作用ロジック /// </summary> public partial class MainView : Window { public MainView(MainViewModel viewModel) { DataContext = viewModel; InitializeComponent(); } } } |
次にMainView.xaml
にElement
の個数を表示するためのText
コントロールを配置し、MainViewModel
のElementsCount
プロパティにバインドします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<Window x:Class="RevitAddinTemplate.MainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:RevitAddinTemplate" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <StackPanel> <TextBlock Text="Revitドキュメント内に見つかったElementは" FontSize="24" FontWeight="Bold" Margin="10"/> <TextBlock Text="{Binding ElementsCount}" FontSize="24" FontWeight="Bold" Margin="10"/> <TextBlock Text="個でした。" FontSize="24" FontWeight="Bold" Margin="10"/> </StackPanel> </Window> |
つくったUIをRevitアドインから呼び出す
Revitアドインに必要な実装を追加します。
IExternalApplication
インターフェイスを実装したApp
クラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#region Namespaces using System.Reflection; using Autodesk.Revit.UI; #endregion namespace RevitAddinTemplate { class App : IExternalApplication { public string EXECUTION_PATH = Assembly.GetExecutingAssembly().Location; public Result OnStartup(UIControlledApplication ap) { RibbonPanel panel = ap.CreateRibbonPanel("RevitAddinTemplate"); PushButtonData quickButton = new PushButtonData("RevitAddinTemplate", "RevitAddinTemplate", EXECUTION_PATH, "RevitAddinTemplate.Model"); panel.AddItem(quickButton); return Result.Succeeded; } public Result OnShutdown(UIControlledApplication a) { return Result.Succeeded; } } } |
アドインのエントリポイントになります。
IExternalCommand
インターフェイスを実装したModel
クラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.UI; namespace RevitAddinTemplate { [Transaction(TransactionMode.Manual)] public class Model : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { var uidoc = commandData.Application.ActiveUIDocument; var doc = uidoc.Document; var elementsCount = new FilteredElementCollector(doc).GetElementCount(); var viewModel = new MainViewModel { ElementsCount = elementsCount }; var view = new MainView(viewModel); view.ShowDialog(); return Result.Succeeded; } } } |
リボンのボタンに割り当てるコマンドです。
1 |
var elementsCount = new FilteredElementCollector(doc).GetElementCount(); |
の行でElement
の個数を計測し、ViewModel
に渡しています。
1 |
view.ShowDialog(); |
の行でUIがモーダルウィンドウで表示されます。
アドインマニフェスト
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="utf-8"?> <RevitAddIns> <AddIn Type="Application"> <Name>RevitAddinTemplate</Name> <Assembly>RevitAddinTemplate.dll</Assembly> <FullClassName>RevitAddinTemplate.App</FullClassName> <ClientId>D838C94C-E5A3-4324-B7E7-485E3DF0CE92</ClientId> <VendorId>com.amd-lab</VendorId> <VendorDescription>AMDlab Inc., https://amd-lab.com</VendorDescription> </AddIn> </RevitAddIns> |
Revitがアドインのエントリポイントを認識するためのファイルです。
実行
ビルドが通ったら、早速%APPDATA%\Autodesk\Revit\Addins\2024
などにRevitAddinTemplate.dll
とRevitAddinTemplate.addin
を配置してRevitを起動してみましょう。
アドインタブにボタンは作られていますか?
Revitドキュメント内のElementの個数が分かるアドインが作れました。
RUGの構造サンプルには71181個のElementがあるみたいです。
おわりに
RevitAPIで学ぶC#シリーズ、コーディング編の第一弾としてUIについて取り上げてみました。
今回は個数を表示するだけでしたが、UIには色んなコントロールがあります。
例えば、UIでの入力をRevitに反映する双方向なUIなども今後取り上げられればと思います。
弊社では随時BIMエンジニア、コンピュテーショナルデザイナーを募集しています。
ご興味のある方は、DMかContactからご連絡ください。
COMMENTS