Hi,
I want to add a dockable window in my command, but it doesn't work properly.
The dockable pane can be registred, but after that it throws an argument axception "The requested dockable pane hast not been created yet" and i don't know why.
Can anybody help?
Below is the part of my code:
UIApplication application = commandData.Application; // register dockable Window DefaultFamilyTypes DefaultFamilyTypesPane = new DefaultFamilyTypes(); if (!DockablePane.PaneIsRegistered(DefaultFamilyTypes.PaneId)) application.RegisterDockablePane(DefaultFamilyTypes.PaneId, "FamilyLoader", DefaultFamilyTypesPane); else TaskDialog.Show("FamilyLoader", "Pane is registred"); DockablePane pane = application.GetDockablePane(DefaultFamilyTypes.PaneId); pane.Show();
Greets, Michael
Hi,
I want to add a dockable window in my command, but it doesn't work properly.
The dockable pane can be registred, but after that it throws an argument axception "The requested dockable pane hast not been created yet" and i don't know why.
Can anybody help?
Below is the part of my code:
UIApplication application = commandData.Application; // register dockable Window DefaultFamilyTypes DefaultFamilyTypesPane = new DefaultFamilyTypes(); if (!DockablePane.PaneIsRegistered(DefaultFamilyTypes.PaneId)) application.RegisterDockablePane(DefaultFamilyTypes.PaneId, "FamilyLoader", DefaultFamilyTypesPane); else TaskDialog.Show("FamilyLoader", "Pane is registred"); DockablePane pane = application.GetDockablePane(DefaultFamilyTypes.PaneId); pane.Show();
Greets, Michael
Hi,
further information would be helpful.
For example, there may be another addin having the pane's guid already registered.
Or, in your DefaultFamilyTypes class, implementing IDockablePaneProvider interface.
In its SetupDockablePane method, there is something to do, as RevitAPI.chm states:
"Container for information about the new dockable pane. Implementers should set the FrameworkElement and InitialState Properties. Optionally, providers can set the ContextualHelp property if they wish to provide or react to help requests on the pane, or override the default EditorInteraction property by setting it here."
Revitalizer
Hi,
further information would be helpful.
For example, there may be another addin having the pane's guid already registered.
Or, in your DefaultFamilyTypes class, implementing IDockablePaneProvider interface.
In its SetupDockablePane method, there is something to do, as RevitAPI.chm states:
"Container for information about the new dockable pane. Implementers should set the FrameworkElement and InitialState Properties. Optionally, providers can set the ContextualHelp property if they wish to provide or react to help requests on the pane, or override the default EditorInteraction property by setting it here."
Revitalizer
Hi,
thanks for your answer.
The IDockablePaneProvider ist already implemented, in the SetupDockablePane methode it's all set:
public void SetupDockablePane(DockablePaneProviderData data) { data.VisibleByDefault = true; data.FrameworkElement = this; data.InitialState.DockPosition = DockPosition.Left; }
I also tried it with a newly created guid, but that ain't work.
Maybe there's a problem because of using the UIApplication instead of the UIControlledApplication?
Michael
Hi,
thanks for your answer.
The IDockablePaneProvider ist already implemented, in the SetupDockablePane methode it's all set:
public void SetupDockablePane(DockablePaneProviderData data) { data.VisibleByDefault = true; data.FrameworkElement = this; data.InitialState.DockPosition = DockPosition.Left; }
I also tried it with a newly created guid, but that ain't work.
Maybe there's a problem because of using the UIApplication instead of the UIControlledApplication?
Michael
Hello, i am experiencing the same issue, do you happen to have any solution for this??
Hello, i am experiencing the same issue, do you happen to have any solution for this??
我遇到了类似的问题,有时候在关闭Revit2016时,发生异常:
The requested dockable pane has not been created yet.
我遇到了类似的问题,有时候在关闭Revit2016时,发生异常:
The requested dockable pane has not been created yet.
I'm experiencing the same issue. Have you managed to resolve yours?
Even Jeremy's sample shows the same error ".... parameter name: id"
I'm experiencing the same issue. Have you managed to resolve yours?
Even Jeremy's sample shows the same error ".... parameter name: id"
Hi
Use Initialization event to register:
public class App : IExternalApplication
{
#region external application public methods
/// <summary>
/// Called when Revit starts up.
/// </summary>
/// <param name="application"></param>
/// <returns></returns>
public Result OnStartup(UIControlledApplication application)
{
UIContApp = application;
//UIApp = GetUiApplication();
//Initialize whole plugin's user interface
RibbonSetup.Initialize(application);
application.ControlledApplication.ApplicationInitialized += RemoraApplicationInitialized;
return Result.Succeeded;
}
/// <summary>
/// Shutdown command
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public Result OnShutdown(UIControlledApplication application)
{
application.ControlledApplication.ApplicationInitialized -= RemoraApplicationInitialized;
return Result.Succeeded;
}
#endregion
#region Events
public void RemoraApplicationInitialized(object sender, ApplicationInitializedEventArgs e)
{
RegisterRemoraCommand regcommand = new RegisterRemoraCommand();
regcommand.Execute(new UIApplication(sender as Application));
}
#endregion
}
View.cs:
public partial class RemoraView : Page ,IDisposable, IDockablePaneProvider
{
public RemoraView()
{
this.DataContext = new RemoraVM();
}
public void Dispose()
{
this.Dispose();
}
public void SetupDockablePane(DockablePaneProviderData data)
{
data.FrameworkElement = this as FrameworkElement;
DockablePaneState dockpanestate = new DockablePaneState();
data.InitialState = new DockablePaneState
{
DockPosition = DockPosition.Right,
};
}
}
Register Command:
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class RegisterRemoraCommand : IExternalCommand
{
public RemoraView dockedremorawindow = new RemoraView();
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
return Execute(commandData.Application);
}
public Result Execute(UIApplication uiapp)
{
DockablePaneProviderData data = new DockablePaneProviderData();
data.FrameworkElement = dockedremorawindow as FrameworkElement;
DockablePaneState state = new DockablePaneState
{
DockPosition = DockPosition.Right,
};
DockablePaneId dpid = new DockablePaneId(new Guid("{Put your new guid here}"));
uiapp.RegisterDockablePane(dpid, "Remora", dockedremorawindow as IDockablePaneProvider);
return Result.Succeeded;
}
#endregion
}
I hope this helps.
Hi
Use Initialization event to register:
public class App : IExternalApplication
{
#region external application public methods
/// <summary>
/// Called when Revit starts up.
/// </summary>
/// <param name="application"></param>
/// <returns></returns>
public Result OnStartup(UIControlledApplication application)
{
UIContApp = application;
//UIApp = GetUiApplication();
//Initialize whole plugin's user interface
RibbonSetup.Initialize(application);
application.ControlledApplication.ApplicationInitialized += RemoraApplicationInitialized;
return Result.Succeeded;
}
/// <summary>
/// Shutdown command
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public Result OnShutdown(UIControlledApplication application)
{
application.ControlledApplication.ApplicationInitialized -= RemoraApplicationInitialized;
return Result.Succeeded;
}
#endregion
#region Events
public void RemoraApplicationInitialized(object sender, ApplicationInitializedEventArgs e)
{
RegisterRemoraCommand regcommand = new RegisterRemoraCommand();
regcommand.Execute(new UIApplication(sender as Application));
}
#endregion
}
View.cs:
public partial class RemoraView : Page ,IDisposable, IDockablePaneProvider
{
public RemoraView()
{
this.DataContext = new RemoraVM();
}
public void Dispose()
{
this.Dispose();
}
public void SetupDockablePane(DockablePaneProviderData data)
{
data.FrameworkElement = this as FrameworkElement;
DockablePaneState dockpanestate = new DockablePaneState();
data.InitialState = new DockablePaneState
{
DockPosition = DockPosition.Right,
};
}
}
Register Command:
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class RegisterRemoraCommand : IExternalCommand
{
public RemoraView dockedremorawindow = new RemoraView();
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
return Execute(commandData.Application);
}
public Result Execute(UIApplication uiapp)
{
DockablePaneProviderData data = new DockablePaneProviderData();
data.FrameworkElement = dockedremorawindow as FrameworkElement;
DockablePaneState state = new DockablePaneState
{
DockPosition = DockPosition.Right,
};
DockablePaneId dpid = new DockablePaneId(new Guid("{Put your new guid here}"));
uiapp.RegisterDockablePane(dpid, "Remora", dockedremorawindow as IDockablePaneProvider);
return Result.Succeeded;
}
#endregion
}
I hope this helps.
Any news on this ? I have the same problem and I can't get it to work.
Any news on this ? I have the same problem and I can't get it to work.
Did you try the example shown above? Post full class code and I can help debug and solve the problem.
Did you try the example shown above? Post full class code and I can help debug and solve the problem.
I used the same code but not in the OnStartup Method.
When I have so time i will try it this way to see if the is related.
I used the same code but not in the OnStartup Method.
When I have so time i will try it this way to see if the is related.
The "onstartup" method triggers an event "RemoraApplicationInitializated" which then executes the RegisterRemoraCommand.Execute method. This registers the dockable pane automatically when the program starts up. I would guess a majority of the time this would be the desired behavior. The alternative is using something similar to the SDK samples where there is a separate button that registers the dockable pane, which requires you track whether it has been registered or not by the user.
The "onstartup" method triggers an event "RemoraApplicationInitializated" which then executes the RegisterRemoraCommand.Execute method. This registers the dockable pane automatically when the program starts up. I would guess a majority of the time this would be the desired behavior. The alternative is using something similar to the SDK samples where there is a separate button that registers the dockable pane, which requires you track whether it has been registered or not by the user.
I was testing some similar last week and I was not able to show a Dockable Pane without register properly on the ApplicationInitialized.
Maybe is by design like Warning, is not possible to register a Warning on the fly, only on the ApplicationInitialized.
The quote below is about CreateFailureDefinition.
"The newly created FailureDefinition will be added to the FailureDefinitionRegistry. Because FailureDefinition could only be registered when Revit starting up, this function cannot be used after Revit has already started. Throws InvalidOperationException if invoked after Revit start-up is completed."
I was testing some similar last week and I was not able to show a Dockable Pane without register properly on the ApplicationInitialized.
Maybe is by design like Warning, is not possible to register a Warning on the fly, only on the ApplicationInitialized.
The quote below is about CreateFailureDefinition.
"The newly created FailureDefinition will be added to the FailureDefinitionRegistry. Because FailureDefinition could only be registered when Revit starting up, this function cannot be used after Revit has already started. Throws InvalidOperationException if invoked after Revit start-up is completed."
Thank you for the insight @ricaun .
That's what I had in mind too (design like Warning). But I hadn't the time to test it right now.
However it is wierd that it is not documented and that many exemples are made outside of initialization.
Maybe it changed with latest release ?
I'll give it a try in the days to come.
Best regards
Thank you for the insight @ricaun .
That's what I had in mind too (design like Warning). But I hadn't the time to test it right now.
However it is wierd that it is not documented and that many exemples are made outside of initialization.
Maybe it changed with latest release ?
I'll give it a try in the days to come.
Best regards
Hello, Anyone found the solution please help me, I get the same problem. the enclosed file is my project.
Hello, Anyone found the solution please help me, I get the same problem. the enclosed file is my project.
It was my understanding that dockable panes can only be registered within the OnStartup method. Late registration for Dockable panes is not allowed. (My understanding comes from prior experimenting, no specific documentation somewhere.)
It was my understanding that dockable panes can only be registered within the OnStartup method. Late registration for Dockable panes is not allowed. (My understanding comes from prior experimenting, no specific documentation somewhere.)
I have same problem. If i register it using UIpplication.ControlledApplication.ApplicationInitialized += RegLaunchPane; event at OnStartup(); it does not register it and I get:
Autodesk.Revit.Exceptions.ArgumentException:
'No dockable pane has been registered with this identifier.
Parameter name: id'
If I do the registration without event and just call this method at OnStartup();:
private void RegisterDockPanel(UIControlledApplication app)
{
ViewPane viewPane = new ViewPane();
DockablePaneId dpid = new DockablePaneId(DockablePaneIdentifierManager.GetPanelIdentifier());
app.RegisterDockablePane(dpid, "DockPanel Name", viewPane as IDockablePaneProvider);
}
The ViewPane Page is registered and shown ONLY if I exclude InitializeComponent(); from ViewPane() Page class.
public ViewPane()
{
Debug.WriteLine("[ViewPane]");
//InitializeComponent();
// If I include InitializeComponent, I get System.IO.FileNotFoundException: 'Could not load file or assembly
}
Then I get black pane because it's not initialized.
If I leave InitializeComponent(); I get:
System.IO.FileNotFoundException
HResult=0x80070002
Message=Could not load file or assembly 'MyAssambley, Version=0.0.0, Culture=neutral' or one of its dependencies. The system cannot find the file specified.
Source=mscorlib
when the ViewPane instance is created at Registration stage.
I use Revit 2024.1
I have same problem. If i register it using UIpplication.ControlledApplication.ApplicationInitialized += RegLaunchPane; event at OnStartup(); it does not register it and I get:
Autodesk.Revit.Exceptions.ArgumentException:
'No dockable pane has been registered with this identifier.
Parameter name: id'
If I do the registration without event and just call this method at OnStartup();:
private void RegisterDockPanel(UIControlledApplication app)
{
ViewPane viewPane = new ViewPane();
DockablePaneId dpid = new DockablePaneId(DockablePaneIdentifierManager.GetPanelIdentifier());
app.RegisterDockablePane(dpid, "DockPanel Name", viewPane as IDockablePaneProvider);
}
The ViewPane Page is registered and shown ONLY if I exclude InitializeComponent(); from ViewPane() Page class.
public ViewPane()
{
Debug.WriteLine("[ViewPane]");
//InitializeComponent();
// If I include InitializeComponent, I get System.IO.FileNotFoundException: 'Could not load file or assembly
}
Then I get black pane because it's not initialized.
If I leave InitializeComponent(); I get:
System.IO.FileNotFoundException
HResult=0x80070002
Message=Could not load file or assembly 'MyAssambley, Version=0.0.0, Culture=neutral' or one of its dependencies. The system cannot find the file specified.
Source=mscorlib
when the ViewPane instance is created at Registration stage.
I use Revit 2024.1
On revisiting this post, I'm not sure if the OP found a solution to their problem, but this could also be one of timing. You should actively register your pane within the OnStartup method.
As a follow-up, I suspect registered panes can only be accessed after (or inside of) the ApplicationInitialized event thrown by Revit itself - as mentioned by @ricaun. This is where Revit has actually created references to the panes you have previously registered.
Would be interested in the OP to try it out and let us know what you find.
On revisiting this post, I'm not sure if the OP found a solution to their problem, but this could also be one of timing. You should actively register your pane within the OnStartup method.
As a follow-up, I suspect registered panes can only be accessed after (or inside of) the ApplicationInitialized event thrown by Revit itself - as mentioned by @ricaun. This is where Revit has actually created references to the panes you have previously registered.
Would be interested in the OP to try it out and let us know what you find.
I am using <Project Sdk="Microsoft.NET.Sdk"> style project. All dlls are copied to Addin folder when Debuging. The ("MyAssambley") that is missing in InitializeComponent(); is my addins MyAssambley.dll and is copied in Addin folder.
I am using <Project Sdk="Microsoft.NET.Sdk"> style project. All dlls are copied to Addin folder when Debuging. The ("MyAssambley") that is missing in InitializeComponent(); is my addins MyAssambley.dll and is copied in Addin folder.
if i may offer up an alternative approach, in my office, we have 4 dockable pane applications loading each time, we found that registering within each addin did not work, its been awhile since we first did this, but i suspect similar issue. Instead, we run postcommand inside a loader.dll (this also loads a bunch of other custom addins, but not important).
Heres the relevant code.
From the loader dll:
private void RevitisIdling(object sender, IdlingEventArgs e)
{
UIApplication _uiapp = sender as UIApplication;
RevitCommandId typ_det_cmd =
RevitCommandId.LookupCommandId("81799b43-c658-4233-a362-cc232d9fc06c");
if (_uiapp.CanPostCommand(typ_det_cmd))
{
_uiapp.PostCommand(typ_det_cmd);
}
_uiapp.Idling -= RevitisIdling;
}
Dockable Application Registration Command, from Command.cs
[Transaction(TransactionMode.Manual)]
public class TypDetailRegister : IExternalCommand
{
private TypDetForm TheForm;
private Application _app;
private UIApplication _uiapp;
private List<ViewProperties> _viewList = new List<ViewProperties>();
private ExternalCommandData _commdata;
private Document _typdoc;
private Document _doc;
DockablePane _pane;
public Result Execute(ExternalCommandData commdata, ref string msg, ElementSet elemset)
{
_commdata = commdata;
_uiapp = _commdata.Application;
_app = _uiapp.Application;
TheForm = new TypDetForm();
_uiapp.RegisterDockablePane(GlobalVars.dockid, "Typ Detail Selector", TheForm as IDockablePaneProvider); //register the dockbable pane
_app.DocumentOpening += NotQuiteOpen; //event for right before a project is opened
_app.DocumentOpened += TypDetViews; //event for after the project finishes opening
_app.DocumentClosing += NotQuiteClosed; //event for right beforea proejct is closed
//update the list when a view is activated or the pane is opened
//_uiapp.ViewActivated += Application_ViewActivated;
_uiapp.DockableFrameVisibilityChanged += Application_VisibilityChanged;
return Result.Succeeded;
}
}
public class GlobalVars
{
public static DockablePaneId dockid = new DockablePaneId(new Guid("81799b43-c658-4233-a362-cc232d9fc06c"));
public static bool DoTheThings { get; set; }
}
Setup of the dockable pane itself, from xaml.cs:
public partial class TypDetForm : Page, IDockablePaneProvider
{
private TypDetailRegister TypDetViews;
public Document TypDoc;
private Document ThisDoc;
private Application App;
private UIApplication UiApp;
private CheckBox _headerBlock;
private Expander _localexp;
private bool _txtexpansion = false; //bool to force "whole word" search on space bar
public TypDetForm()
{
InitializeComponent();
}
public void SetupDockablePane(DockablePaneProviderData data)//set some default parameters
{
data.FrameworkElement = this;
data.InitialState = new DockablePaneState();
data.InitialState.DockPosition = DockPosition.Right;
}
}
and Lastly, showing the form, from Command.cs:
[Transaction(TransactionMode.Manual)]
public class TypDetailShow : IExternalCommand
{//this class is literally just for show....shows the form.
public Result Execute(ExternalCommandData commdata, ref string msg, ElementSet elemset)
{
try
{
UIApplication _uiapp = commdata.Application;
DockablePane pane = _uiapp.GetDockablePane(GlobalVars.dockid);
//if the window is displayed when the button is clicked, hide the window and uncheck the box
if (pane.IsShown())
{
pane.Hide();
}
//otherwise, show the window and check the box
else
{
pane.Show();
}
}
catch (Exception ex)
{
// show error info dialog
TaskDialog.Show("Info Message", ex.Message);
}
return Result.Succeeded;
}
}
if i may offer up an alternative approach, in my office, we have 4 dockable pane applications loading each time, we found that registering within each addin did not work, its been awhile since we first did this, but i suspect similar issue. Instead, we run postcommand inside a loader.dll (this also loads a bunch of other custom addins, but not important).
Heres the relevant code.
From the loader dll:
private void RevitisIdling(object sender, IdlingEventArgs e)
{
UIApplication _uiapp = sender as UIApplication;
RevitCommandId typ_det_cmd =
RevitCommandId.LookupCommandId("81799b43-c658-4233-a362-cc232d9fc06c");
if (_uiapp.CanPostCommand(typ_det_cmd))
{
_uiapp.PostCommand(typ_det_cmd);
}
_uiapp.Idling -= RevitisIdling;
}
Dockable Application Registration Command, from Command.cs
[Transaction(TransactionMode.Manual)]
public class TypDetailRegister : IExternalCommand
{
private TypDetForm TheForm;
private Application _app;
private UIApplication _uiapp;
private List<ViewProperties> _viewList = new List<ViewProperties>();
private ExternalCommandData _commdata;
private Document _typdoc;
private Document _doc;
DockablePane _pane;
public Result Execute(ExternalCommandData commdata, ref string msg, ElementSet elemset)
{
_commdata = commdata;
_uiapp = _commdata.Application;
_app = _uiapp.Application;
TheForm = new TypDetForm();
_uiapp.RegisterDockablePane(GlobalVars.dockid, "Typ Detail Selector", TheForm as IDockablePaneProvider); //register the dockbable pane
_app.DocumentOpening += NotQuiteOpen; //event for right before a project is opened
_app.DocumentOpened += TypDetViews; //event for after the project finishes opening
_app.DocumentClosing += NotQuiteClosed; //event for right beforea proejct is closed
//update the list when a view is activated or the pane is opened
//_uiapp.ViewActivated += Application_ViewActivated;
_uiapp.DockableFrameVisibilityChanged += Application_VisibilityChanged;
return Result.Succeeded;
}
}
public class GlobalVars
{
public static DockablePaneId dockid = new DockablePaneId(new Guid("81799b43-c658-4233-a362-cc232d9fc06c"));
public static bool DoTheThings { get; set; }
}
Setup of the dockable pane itself, from xaml.cs:
public partial class TypDetForm : Page, IDockablePaneProvider
{
private TypDetailRegister TypDetViews;
public Document TypDoc;
private Document ThisDoc;
private Application App;
private UIApplication UiApp;
private CheckBox _headerBlock;
private Expander _localexp;
private bool _txtexpansion = false; //bool to force "whole word" search on space bar
public TypDetForm()
{
InitializeComponent();
}
public void SetupDockablePane(DockablePaneProviderData data)//set some default parameters
{
data.FrameworkElement = this;
data.InitialState = new DockablePaneState();
data.InitialState.DockPosition = DockPosition.Right;
}
}
and Lastly, showing the form, from Command.cs:
[Transaction(TransactionMode.Manual)]
public class TypDetailShow : IExternalCommand
{//this class is literally just for show....shows the form.
public Result Execute(ExternalCommandData commdata, ref string msg, ElementSet elemset)
{
try
{
UIApplication _uiapp = commdata.Application;
DockablePane pane = _uiapp.GetDockablePane(GlobalVars.dockid);
//if the window is displayed when the button is clicked, hide the window and uncheck the box
if (pane.IsShown())
{
pane.Hide();
}
//otherwise, show the window and check the box
else
{
pane.Show();
}
}
catch (Exception ex)
{
// show error info dialog
TaskDialog.Show("Info Message", ex.Message);
}
return Result.Succeeded;
}
}
Can't find what you're looking for? Ask the community or share your knowledge.