Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Dockable Pane can't be created

22 REPLIES 22
Reply
Message 1 of 23
michael.kerscher
5328 Views, 22 Replies

Dockable Pane can't be created

michael.kerscher
Participant
Participant

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

 

0 Likes

Dockable Pane can't be created

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

 

22 REPLIES 22
Message 2 of 23

Revitalizer
Advisor
Advisor

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




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes

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




Rudolf Honke
Software Developer
Mensch und Maschine





Message 3 of 23

michael.kerscher
Participant
Participant

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

0 Likes

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

Message 4 of 23

junkang.lau
Contributor
Contributor

Hello, i am experiencing the same issue, do you happen to have any solution for this??

0 Likes

Hello, i am experiencing the same issue, do you happen to have any solution for this??

Message 5 of 23
ChengboZhang
in reply to: Revitalizer

ChengboZhang
Enthusiast
Enthusiast

我遇到了类似的问题,有时候在关闭Revit2016时,发生异常:

The requested dockable pane has not been created yet.

 

0 Likes

我遇到了类似的问题,有时候在关闭Revit2016时,发生异常:

The requested dockable pane has not been created yet.

 

Message 6 of 23
lumoric
in reply to: michael.kerscher

lumoric
Contributor
Contributor

I'm experiencing the same issue. Have you managed to resolve yours?

Even Jeremy's sample shows the same error ".... parameter name: id"

 

0 Likes

I'm experiencing the same issue. Have you managed to resolve yours?

Even Jeremy's sample shows the same error ".... parameter name: id"

 

Message 7 of 23
normnoe
in reply to: michael.kerscher

normnoe
Participant
Participant

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.

0 Likes

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.

Message 8 of 23

francois.robberts467QG
Participant
Participant

Any news on this ? I have the same problem and I can't get it to work.

0 Likes

Any news on this ? I have the same problem and I can't get it to work.

Message 9 of 23

normnoe
Participant
Participant

Did you try the example shown above?  Post full class code and I can help debug and solve the problem.

0 Likes

Did you try the example shown above?  Post full class code and I can help debug and solve the problem.

Message 10 of 23

francois.robberts467QG
Participant
Participant

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.

0 Likes

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.

Message 11 of 23
normnoe
in reply to: michael.kerscher

normnoe
Participant
Participant

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.

0 Likes

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.

Message 12 of 23
ricaun
in reply to: michael.kerscher

ricaun
Advisor
Advisor

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

 

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

0 Likes

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

 

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

Message 13 of 23

francois.robberts467QG
Participant
Participant

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

0 Likes

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

Message 14 of 23
tamsann
in reply to: michael.kerscher

tamsann
Enthusiast
Enthusiast

photo_2023-09-01_17-51-27.jpg

Hello, Anyone found the solution please help me, I get the same problem. the enclosed file is my project.

0 Likes

photo_2023-09-01_17-51-27.jpg

Hello, Anyone found the solution please help me, I get the same problem. the enclosed file is my project.

Message 15 of 23

rhanzlick
Advocate
Advocate

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

0 Likes

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

Message 16 of 23
esatis
in reply to: rhanzlick

esatis
Advocate
Advocate

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

0 Likes

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

Message 17 of 23
rhanzlick
in reply to: esatis

rhanzlick
Advocate
Advocate
InitializeComponent(); within the constructor is a .Net thing, not a Revit thing. It is required for all applications that show a UI window in the Windows OS. The message from your error looks like your external application requires an external reference dll ("MyAssambley") that it cannot find.

By default, Revit (and .Net) look in the same folder as the .dll file to load resources. If you have set up your addin to require a separate C# project or have dependencies on any other assembly files, they should be placed within the addins folder along with your main assembly file.
0 Likes

InitializeComponent(); within the constructor is a .Net thing, not a Revit thing. It is required for all applications that show a UI window in the Windows OS. The message from your error looks like your external application requires an external reference dll ("MyAssambley") that it cannot find.

By default, Revit (and .Net) look in the same folder as the .dll file to load resources. If you have set up your addin to require a separate C# project or have dependencies on any other assembly files, they should be placed within the addins folder along with your main assembly file.
Message 18 of 23

rhanzlick
Advocate
Advocate

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.

0 Likes

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.

Message 19 of 23
esatis
in reply to: rhanzlick

esatis
Advocate
Advocate

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. 

0 Likes

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. 

Message 20 of 23
ctm_mka
in reply to: michael.kerscher

ctm_mka
Advocate
Advocate

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

  • First, both the loader and dockable application have .addin file associated with them.
  • With the loader addin, the dockable registration through postcommand is called in the Idling event, after everything else is run. The form is not shown at this point
  • The loader addin also creates a button for showing the form when needed.

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

 

0 Likes

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

  • First, both the loader and dockable application have .addin file associated with them.
  • With the loader addin, the dockable registration through postcommand is called in the Idling event, after everything else is run. The form is not shown at this point
  • The loader addin also creates a button for showing the form when needed.

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.

Post to forums  

Autodesk Design & Make Report