💭

RevitのMacroでC#はじめよう UI編

2021/02/27に公開

PanelとButtonをつくる

TokyoAECRibbon.addinを用意する

<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
  <AddIn Type="Application">
    <Name>TokyoAECRibbon</Name>
    <Assembly>..\..\Macros\2020\Revit\AppHookup\TokyoAECRibbon\AddIn\TokyoAECRibbon.dll</Assembly>
    <AddInId>ADB959CC-C1DD-4C14-905C-ECE9CCF9B8BC</AddInId>
    <FullClassName>TokyoAECRibbon.ThisApplication</FullClassName>
    <VendorId>GEL</VendorId>
    <VendorDescription>GEL ,geometryengineeringlab.tech</VendorDescription>
  </AddIn>
</RevitAddIns>

Command用のModuleをつくる

  • ClassにIExternalCommandをつける
  • Functionの引数にUIDocumentをいれる
using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Linq;

namespace TokyoAECExternal
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.DB.Macros.AddInId("5EB9308B-CD44-4632-BB99-D1BEC26738C1")]
    public partial class ThisApplication : IExternalCommand
	{
    	public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            myButtonMacro(commandData.Application.ActiveUIDocument);
            return Result.Succeeded;
        }
    	
		private void Module_Startup(object sender, EventArgs e)
		{

		}

		private void Module_Shutdown(object sender, EventArgs e)
		{

		}

		#region Revit Macros generated code
		private void InternalStartup()
		{
			this.Startup += new System.EventHandler(Module_Startup);
			this.Shutdown += new System.EventHandler(Module_Shutdown);
		}
		
		#endregion
		
		public void myButtonMacro(UIDocument uidoc)
		{
			//var uidoc = this.ActiveUIDocument;
			//hello world!
			TaskDialog.Show("Title","Hello World!");
			var doc = uidoc.Document;
			var walls = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Windows).ToElementIds();
			
			uidoc.Selection.SetElementIds(walls);
		}
		
		
		
	}
}

Application用のModuleをつくる

3つをReferenceに追加する

  • System.Xaml
  • WindowsBase
  • PresentationCore

Result OnShutdown、Result OnStartupを追加する

using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Linq;

using System.Reflection;
using System.IO;
using System.Windows.Media.Imaging;

namespace TokyoAECRibbon
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.DB.Macros.AddInId("ADB959CC-C1DD-4C14-905C-ECE9CCF9B8BC")]
    public partial class ThisApplication : IExternalApplication
    {
    	public Result OnShutdown(UIControlledApplication a)
        {  return Result.Succeeded; }

        public Result OnStartup(UIControlledApplication a)
        {
            string tabName = "TokyoAECRibbon";
            string panelName = "myPanel";
            string path = Assembly.GetExecutingAssembly().Location; 
                                                              
            string assemblyName = Path.GetDirectoryName(path) + "\\TokyoAECRibbon.dll";
            a.CreateRibbonTab(tabName);
            RibbonPanel PRLChecklistsPanel = a.CreateRibbonPanel(tabName, panelName);
            string buttonName = "myButtonMacro";
            PushButtonData myPushButtonData = new PushButtonData(buttonName, buttonName, assemblyName, "TokyoAECRibbon.Invoke");

            myPushButtonData.LargeImage = new BitmapImage(new Uri(Path.Combine(Path.GetDirectoryName(path) + "\\coffee-icon.png"), UriKind.Absolute));
            RibbonItem myRibbonItem = PRLChecklistsPanel.AddItem(myPushButtonData);

            return Result.Succeeded;
        }
        #region Revit Macros generated code
		private void Module_Startup(object sender, EventArgs e)
		{

		}

		private void Module_Shutdown(object sender, EventArgs e)
		{

		}

		
		private void InternalStartup()
		{
			this.Startup += new System.EventHandler(Module_Startup);
			this.Shutdown += new System.EventHandler(Module_Shutdown);
		}
		#endregion
	}
    
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]	

    public class Invoke : IExternalCommand
    {
        //public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            string path = Assembly.GetExecutingAssembly().Location;
            
            string assemblyPath = Path.GetDirectoryName(path) + "..\\..\\..\\" + "TokyoAECExternal\\AddIn\\TokyoAECExternal.dll";
            string assemblyDir = Path.GetDirectoryName(path) + "..\\..\\..\\" + "TokyoAECExternal\\AddIn";

            string commandName = "ThisApplication";

            byte[] assemblyBytes = File.ReadAllBytes(assemblyPath);

            Assembly objAssembly = Assembly.Load(assemblyBytes);
            IEnumerable<Type> myIEnumerableType = GetTypesSafely(objAssembly);
            foreach (Type objType in myIEnumerableType)
            {
                if (objType.IsClass)
                {
                    if (objType.Name.ToLower() == commandName.ToLower())
                    {
                        object ibaseObject = Activator.CreateInstance(objType);
                        object[] arguments = new object[] { commandData, assemblyDir, elements };
                        object result = null;

                        result = objType.InvokeMember("Execute", BindingFlags.Default | BindingFlags.InvokeMethod, null, ibaseObject, arguments);

                        break; 
                    }
                }
            }
            return Result.Succeeded;     

        }
        private static IEnumerable<Type> GetTypesSafely(Assembly assembly)
        {
            try
            {
                return assembly.GetTypes();
            }
            catch (ReflectionTypeLoadException ex)
            {
                return ex.Types.Where(x => x != null);
            }
        }
     }
}

Discussion