Dockable External Command Error

Dockable External Command Error

software
Explorer Explorer
771 Views
3 Replies
Message 1 of 4

Dockable External Command Error

software
Explorer
Explorer

Hello, I'm trying to make my own API utilizing the function "Dockable Dialog".

So I've made some docks on Revit 2018. Actually it works well if I push the 'RegisterDockableWindow' before I select a model but the problem is that there is an error about 'External Command' if I select a model first. I don't know why so I need your help. In order to explain my situation better and help you guys to understand my situation, I attached some photos when it works and when it doesn't work. Thank you for your help!!

 

The first Scene(Successful)The first Scene(Successful)The second one(Successful)The second one(Successful)The third one(Successful)The third one(Successful)The failed one with the errorThe failed one with the error

0 Likes
772 Views
3 Replies
Replies (3)
Message 2 of 4

zhong_wu
Autodesk Support
Autodesk Support

Can you please provide a minimal reproducible case to prove that?

 

In order to understand what you mean and be able to research possible reasons for the discrepancy between the observed and expected behaviour, we require:

 

  • A short exact description of what you are trying to achieve.
  • The behaviour you observe versus what you expect, and why this is a problem.
  • A complete yet minimal Revit sample model to run a test in.
  • A complete yet minimal macro embedded in the sample model or Visual Studio solution with add-in manifest that can be compiled, loaded, run and debugged with a single click to analyse its behaviour live in the sample model.
  • Detailed step-by-step instructions for reproducing the issue.

 Thanks


John Wu
Developer Technical Services
Autodesk Developer Network


0 Likes
Message 3 of 4

software
Explorer
Explorer
  • A short exact description of what you are trying to achieve.

-> What I want to achieve is making this API work well regardless of whether users push the 'Register' button before they select their own model or not. Some users might choose their model first and then want to use the API that I'm developing. But the problem is it is not working if I select a model first and afterwards I try to use the API.

 

  • The behaviour you observe versus what you expect, and why this is a problem.

I expect this API to work if users select a model first or not. I mean it should work in both situations but it's not right now. This is a problem when it comes to user's convenience. We must consider it.

 

  • A complete yet minimal Revit sample model to run a test in.

The file that I have been working on is attached to this reply.

 

  • A complete yet minimal macro embedded in the sample model or Visual Studio solution with add-in manifest that can be compiled, loaded, run and debugged with a single click to analyse its behaviour live in the sample model.

 

  • Detailed step-by-step instructions for reproducing the issue.

First, you should run the code that is attached and it will generate files into your 'C:\ProgramData\Autodesk\Revit\Addins\2018' and then just put 'DockableDialog.addin' into the same folder.Copy and paste the generated files into 'C:\a\vs\DockableDialog\DockableDialog\bin\Debug' and run Revit 2018. You'll see the first scene that I already posted. And if you push the 'Register' button and open your any model, you can see the other 2 functions work but if you select your model first before pushing the 'Register' button, then it will show you an error about 'External Command'. 

 

Thank you for your help and I hope that's going to work.

 

using System;
using System.Reflection;
using System.Windows.Forms;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using DockableDialog.Forms;
using DockableDialog.Properties;

namespace DockableDialog
{
  public class Ribbon : IExternalApplication
  {
    public Result OnStartup( UIControlledApplication a )
    {
      a.CreateRibbonTab( "AEC LABS" );
              
      RibbonPanel AECPanelDebug = a.CreateRibbonPanel( "AEC LABS", "AEC LABS" );

      string path = Assembly.GetExecutingAssembly().Location;

      #region DockableWindow
      PushButtonData pushButtonRegisterDockableWindow = new PushButtonData( "RegisterDockableWindow", "RegisterDockableWindow", path, "DockableDialog.RegisterDockableWindow" );
      pushButtonRegisterDockableWindow.LargeImage = GetImage( Resources.green.GetHbitmap() );
      pushButtonRegisterDockableWindow.AvailabilityClassName = "DockableDialog.AvailabilityNoOpenDocument";

      PushButtonData pushButtonShowDockableWindow = new PushButtonData( "Show DockableWindow", "Show DockableWindow", path, "DockableDialog.ShowDockableWindow" );
      pushButtonShowDockableWindow.LargeImage = GetImage( Resources.red.GetHbitmap() );

      PushButtonData pushButtonHideDockableWindow = new PushButtonData( "Hide DockableWindow", "Hide DockableWindow", path, "DockableDialog.HideDockableWindow" );
      pushButtonHideDockableWindow.LargeImage = GetImage( Resources.orange.GetHbitmap() );
      //IList<RibbonItem> ribbonpushButtonDockableWindow = AECPanelDebug.AddStackedItems(pushButtonRegisterDockableWindow, pushButtonShowDockableWindow, pushButtonHideDockableWindow);

      RibbonItem ri1 = AECPanelDebug.AddItem( pushButtonRegisterDockableWindow );
      RibbonItem ri2 = AECPanelDebug.AddItem( pushButtonShowDockableWindow );
      RibbonItem ri3 = AECPanelDebug.AddItem( pushButtonHideDockableWindow );
      #endregion

      return Result.Succeeded;
    }

    public Result OnShutdown( UIControlledApplication a )
    {
      return Result.Succeeded;
    }

    private System.Windows.Media.Imaging.BitmapSource GetImage( IntPtr bm )
    {
      System.Windows.Media.Imaging.BitmapSource bmSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bm, IntPtr.Zero, System.Windows.Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions() );

      return bmSource;
    }
  }

  /// <summary>
  /// You can only register a dockable dialog in "Zero doc state"
  /// </summary>
  public class AvailabilityNoOpenDocument : IExternalCommandAvailability
  {
    public bool IsCommandAvailable( UIApplication a, CategorySet b )
    {
      if( a.ActiveUIDocument == null )
      {
        return true;
      }
      return false;
    }
  }

  /// <summary>
  /// Register your dockable dialog
  /// </summary>
  [Transaction( TransactionMode.Manual )]
  public class RegisterDockableWindow : IExternalCommand
  {
    MainPage m_MyDockableWindow = null;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements )
    {
      DockablePaneProviderData data = new DockablePaneProviderData();

      MainPage MainDockableWindow = new MainPage();

      m_MyDockableWindow = MainDockableWindow;

      //MainDockableWindow.SetupDockablePane(me);

      data.FrameworkElement = MainDockableWindow as System.Windows.FrameworkElement;

      data.InitialState = new DockablePaneState();

      data.InitialState.DockPosition = DockPosition.Tabbed;

      //DockablePaneId targetPane;
      //if (m_targetGuid == Guid.Empty)
      //    targetPane = null;
      //else targetPane = new DockablePaneId(m_targetGuid);
      //if (m_position == DockPosition.Tabbed)

      data.InitialState.TabBehind = DockablePanes.BuiltInDockablePanes.ProjectBrowser;

      DockablePaneId dpid = new DockablePaneId( new Guid( "{D7C963CE-B7CA-426A-8D51-6E8254D21157}" ) );

      commandData.Application.RegisterDockablePane(dpid, "AEC Dockable Window", MainDockableWindow as IDockablePaneProvider );

      commandData.Application.ViewActivated += new EventHandler<ViewActivatedEventArgs>( Application_ViewActivated );

      return Result.Succeeded;
    }

    void Application_ViewActivated( object sender, ViewActivatedEventArgs e )
    {
            MessageBox.Show(e.Document.ProjectInformation.Name, "1");
      m_MyDockableWindow.lblProjectName.Content = e.Document.ProjectInformation.Name;
    }
  }

  /// <summary>
  /// Show dockable dialog
  /// </summary>
  [Transaction( TransactionMode.ReadOnly )]
  public class ShowDockableWindow : IExternalCommand
  {
    public Result Execute( ExternalCommandData commandData,ref string message, ElementSet elements )
    {
      DockablePaneId dpid = new DockablePaneId( new Guid( "{D7C963CE-B7CA-426A-8D51-6E8254D21157}" ) );

      DockablePane dp = commandData.Application.GetDockablePane( dpid );

            common.P_Name =commandData.Application.ActiveUIDocument.Document.Title;
            MessageBox.Show(common.P_Name, "2");
            dp.Show();

      return Result.Succeeded;
    }
  }

  /// <summary>
  /// Hide dockable dialog
  /// </summary>
  [Transaction( TransactionMode.ReadOnly )]
  public class HideDockableWindow : IExternalCommand
  {
    public Result Execute(
      ExternalCommandData commandData,
      ref string message,
      ElementSet elements )
    {
      DockablePaneId dpid = new DockablePaneId(
        new Guid( "{D7C963CE-B7CA-426A-8D51-6E8254D21157}" ) );

      DockablePane dp = commandData.Application
        .GetDockablePane( dpid );

      dp.Hide();
      return Result.Succeeded;
    }
  }
}
<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
  <AddIn Type="Application">
    <Name>DockableDialog</Name>
    <Assembly>C:\a\vs\DockableDialog\DockableDialog\bin\Debug\DockableDialog.dll</Assembly>
    <AddInId>391067E6-979B-43EF-86AD-7B67B4FB0E96</AddInId>
    <FullClassName>DockableDialog.Ribbon</FullClassName>
    <VendorId>ADSK</VendorId>
    <VendorDescription>Autodesk, www.autodesk.com</VendorDescription>
  </AddIn>
</RevitAddIns>
0 Likes
Message 4 of 4

zhong_wu
Autodesk Support
Autodesk Support

Thanks for your detail description and sample code, but I can not run your code due to classes missing. 

I tried on my side with some similar external application sample, but it seems I did not see the same issue as you mentioned. Looking into your code, I found some interesting thing related to your command, usually we will derive the command from  IExternalCommandAvailability to make it be disable/enable on the specific situation, here is my sample code you can refer, does this help? 

 

 

    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
    public class ExternalCommandRegisterPage : IExternalCommand, IExternalCommandAvailability
    {
        public virtual Result Execute(ExternalCommandData commandData
            , ref string message, ElementSet elements)
        {

            MainPage window = new MainPage();
            window.Show();
            return Result.Succeeded;
        }

        /// <summary>
        /// Onlys show the dialog when no document is open
        /// </summary>
        public bool IsCommandAvailable(UIApplication applicationData, CategorySet selectedCategories)
        {
            if (applicationData.ActiveUIDocument == null)
            {
                return true;
            }
            return false;
        }
    }

If this not solve the problem, can you show me the detail error while running the command after document is opened? That should provide more information about the error/warning. Thanks. 

 


John Wu
Developer Technical Services
Autodesk Developer Network


0 Likes