- 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>