RegisterDockablePane from Eventhandler

RegisterDockablePane from Eventhandler

m_bijsterbosch
Explorer Explorer
1,835 Views
5 Replies
Message 1 of 6

RegisterDockablePane from Eventhandler

m_bijsterbosch
Explorer
Explorer

Hello All,

 

i Just started building addins for Revit, my c# skill are not that good yet, and have  a question about registering a DockableDialog from an event.

All the examples i have found so far work with buttons that the user needs to click, i want it to be registered when Revit starts.

I searched on this forum and on google but i haven't found a solution for this problem.

 

i got the code for the ApplicationInitialized event, if i want to show a taskdialog (as test)  it works fine, if i want to RegisterDockablePane is gives errors with the debug proces(see attached images in the spoiler).

Spoiler
error1.PNGerror2.PNG

the codes is pretty simple i think:

    public class RegisterApp : IExternalApplication
    {
        testform m_MyDockableWindow = null;

        public Result OnStartup(UIControlledApplication a)
        {
            a.ControlledApplication.ApplicationInitialized += OnApplicationInitialized;//call OnApplicationInitialized after revit launches 
            
            a.ControlledApplication.DocumentOpened += new EventHandler<Autodesk.Revit.DB.Events.DocumentOpenedEventArgs>(OnDocumentOpened);

            return Result.Succeeded;
        }


        //OnApplicationInitialized register dockable dialog
        public void OnApplicationInitialized(object sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e)
        {
            UIApplication uiapp = sender as UIApplication;
            Application app = sender as Application;

            DockablePaneProviderData data = new DockablePaneProviderData();

            testform MainDockableWindow = new testform();
            m_MyDockableWindow = MainDockableWindow;
            
            data.FrameworkElement = MainDockableWindow as System.Windows.FrameworkElement;

            data.InitialState = new DockablePaneState();

            data.InitialState.DockPosition = DockPosition.Tabbed;
            
            data.InitialState.TabBehind = DockablePanes.BuiltInDockablePanes.PropertiesPalette;

            DockablePaneId dpid = new DockablePaneId(new Guid("{54761517-118C-4A9A-938D-62384E4BAD72}"));
            
            uiapp.RegisterDockablePane(dpid, "name of dockable pane", MainDockableWindow as IDockablePaneProvider);//this line give an error, everything above works fine
            
            TaskDialog td = new TaskDialog("The applicationInitializedEvent worked");//this taskdialog is a test to see if the code works
            td.Show();
}

 

 Is it possible to register with an event, if so, how?

 

 

 

Thanks

Martin B

0 Likes
1,836 Views
5 Replies
Replies (5)
Message 2 of 6

ogaryu
Autodesk Support
Autodesk Support

Dear Martin B,

 

I found the relative discussions on the forum.

 

https://forums.autodesk.com/t5/revit-api/how-to-load-a-rvt-file-automatically-when-start-the-revit/t...

 

>>

The sender object is an Application instance, not UIApplication.

However, UIApplication can be instantiated from Application.

>>

 

So please try this on OnApplicationInitialized event.

 

Application app = sender as Application;
UIApplication uiapp = new UIApplication(app);

 

Best Regards,

Ryuji

Ryuji Ogasawara
Developer Technical Services
Autodesk Developer Network
0 Likes
Message 3 of 6

m_bijsterbosch
Explorer
Explorer

Dear Ryuji,

 

Thanks for the reply.

Your post makes sense however with the changes you suggest it still does not work.

uiapp.RegisterDockablePane(dpid, "name of dockable pane", MainDockableWindow as IDockablePaneProvider); 

still give an error, i built in an try catch to see what the error is, object reference not set to an instance of an object.

errormessage.PNG

the only two objects called in this line are the uiapp and the maindockable window and both are as far as i know instantiated.

Am i missing something obvious?

 

I also added the vs project as attachment if that is of any use.

 

 

Best Regards,

Martin B

 

0 Likes
Message 4 of 6

ogaryu
Autodesk Support
Autodesk Support

 

Firstly,  you can set the UIControlledApplication object to global variable, then you can access it in OnApplicationInitialized.

Secondly, after registering a dockable pane, you need to call DockablePane.Show() method on document opened event.

The pane's initial position is applied when RegisterDockablePane method called as the specific GUID onto the addin.

 

 

testform m_MyDockableWindow = null;
UIControlledApplication uiapp;
DockablePaneId dpid;

public Result OnStartup(UIControlledApplication UIControlledApp)
{
    uiapp = UIControlledApp;

    uiapp.ControlledApplication.ApplicationInitialized += OnApplicationInitialized;
    uiapp.ControlledApplication.DocumentOpened += OnDocumentOpened;

    return Result.Succeeded;
}

public void OnApplicationInitialized(object sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e)
{
    testform MainDockableWindow = new testform();

    m_MyDockableWindow = MainDockableWindow;

    dpid = new DockablePaneId(new Guid("{54761517-118C-4A9A-938D-62384E4BAD72}"));

    uiapp.RegisterDockablePane(dpid, "name of dockable pane", MainDockableWindow as IDockablePaneProvider);

}

public void OnDocumentOpened(object sender, Autodesk.Revit.DB.Events.DocumentOpenedEventArgs e) { DockablePane dp = uiapp.GetDockablePane(dpid); dp.Show(); }

 

Third, it is recommended that the dockable dialog in the add-in be the class that implements IDockablePaneProvider and that it be subclassed from System.Windows.Controls.Page.

 

 

public partial class testform : Page, Autodesk.Revit.UI.IDockablePaneProvider
    {
        public testform()
        {
            InitializeComponent();
        }

        public void SetupDockablePane(Autodesk.Revit.UI.DockablePaneProviderData data)
        {
            data.FrameworkElement = this as FrameworkElement;

            data.InitialState = new Autodesk.Revit.UI.DockablePaneState();
            data.InitialState.DockPosition = Autodesk.Revit.UI.DockPosition.Tabbed;
data.InitialState.TabBehind = Autodesk.Revit.UI.DockablePanes.BuiltInDockablePanes.ProjectBrowser; }

 

Best Regards,

Ryuji

 

Ryuji Ogasawara
Developer Technical Services
Autodesk Developer Network
Message 5 of 6

m_bijsterbosch
Explorer
Explorer

Dear Ryuji,

 

Sorry for the late reply, i had  a small vacation.

Many Thanks for your reply, it makes the code a lot clearer and easies to understand, unfortunately i still get an error i cant solve.

 public partial class testform : Page, Autodesk.Revit.UI.IDockablePaneProvider
    {
        public testform()
        {
            InitializeComponent();
        }

        public void SetupDockablePane(Autodesk.Revit.UI.DockablePaneProviderData data)
        {
            data.FrameworkElement = this as FrameworkElement;

            data.InitialState = new Autodesk.Revit.UI.DockablePaneState();
            data.InitialState.DockPosition = Autodesk.Revit.UI.DockPosition.Tabbed;
            data.InitialState.TabBehind = Autodesk.Revit.UI.DockablePanes.BuiltInDockablePanes.ProjectBrowser;
        }
    }

error.jpg

 

Apparently the WPFTEST.testform cannot be converted to a Frameworkelement.

Do you have any suggestions?

 

Best Regards,

Martin B

Message 6 of 6

ogaryu
Autodesk Support
Autodesk Support

Dear Martin B,

 

Thank you for providing sample project, and sorry for the late reply.

I checked the code and I could reproduced the same build error.

 

Then I checked the xaml code, and I found the tag name as "UserControl" which does not match for inherited class "Page".

 

In xaml:

<UserControl x:Class="WPFTEST.testform">

...

</UserControl>

 

In class definition:

public partial class testform : Page, Autodesk.Revit.UI.IDockablePaneProvider

 

Please try to change like this:

<Page x:Class="WPFTEST.testform">

...

</Page>

 

Best Regards,

Ryuji

 

Ryuji Ogasawara
Developer Technical Services
Autodesk Developer Network
Ryuji Ogasawara
Developer Technical Services
Autodesk Developer Network