Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Inventor AddIn using WPF

22 REPLIES 22
Reply
Message 1 of 23
Anonymous
4192 Views, 22 Replies

Inventor AddIn using WPF

Just wondering if anyone has tried creating an Inventor addin that uses WPF (instead of WinForms). We are trying it with Inventor 2010 and are running into problems. If anyone has tried it, what kind of success have you had? Thanks!

-Tom
22 REPLIES 22
Message 21 of 23
Anonymous
in reply to: AlexFielder

Just an FYI, if anyone else was looking to solve this problem w/o the use of ElementHost:

 

I figured this solution with extended reference to the MyAddInWithWPF blog post from a good bit of time ago. I am currently attempting to get this to work as shellview for a Caliburn.Micro development to little success.

 

With a basic XAML Window: 

 

<Window x:Class="MyAddIn.Views.CalendarDockedWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyAddIn"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid MaxWidth="500" MaxHeight="300">
        <Button Content="Button" Margin="122,198,10,10"/>
        <CheckBox Content="CheckBox" Margin="10,183,129,0" VerticalAlignment="Top"/>
        <Calendar Margin="10,10,10,52"/>
    </Grid>
</Window>

And a related Code-Behind:

 

    public partial class CalendarDockedWindow : Window, IDockableWindow
    {
        #region /*-------------------- Properties & Fields -------------------------------*/
        private readonly string _internalName;
        private WindowInteropHelper _helper;

        public string InternalName => _internalName;
        public WindowInteropHelper Helper => _helper ?? (_helper = new WindowInteropHelper(this));
        public IntPtr HWND
        {
            get
            {
                Helper.EnsureHandle();
                return Helper.Handle;
            }
        }
        #endregion

        private CalendarDockedWindow() { InitializeComponent(); }

        public CalendarDockedWindow(Inventor.Application app, string clientID, string internalName, string title)
        {
            _internalName = internalName;
            InitializeComponent();

            Inventor.UserInterfaceManager _interfaceManager = app.UserInterfaceManager;
            var dockableWindow = _interfaceManager.DockableWindows.Add(clientID, internalName, title);
            dockableWindow.AddChild(HWND);
            WindowStyle = WindowStyle.None;

            dockableWindow.DisabledDockingStates = (DockingStateEnum.kDockTop & DockingStateEnum.kDockLeft);

            dockableWindow.Caption = title;
            dockableWindow.ShowTitleBar = true;
            Visibility = Visibility.Visible;

            if (dockableWindow.IsCustomized) return;
            dockableWindow.Visible = false;
            dockableWindow.DockingState = Inventor.DockingStateEnum.kFloat;
            dockableWindow.Move(25, 25, dockableWindow.Height, dockableWindow.Width);
        }

    }

//Simply Interface to ensure
public interface IDockableWindow
{
IntPtr HWND { get; }
string InternalName { get; }
WindowInteropHelper Helper { get; }
}

[Note that Window is the Magic Ingredient] As with a Window object I can get the HWND and assign it as a child to the Dockable Window, this code-behind is heavy and a lot of the work should be done elsewhere, but as a proof of concept it is clear.

 

 

I can now create the object with a simple call and collect the window reference in a list to use elsewhere if I need to restrict access or remove based on environment:

        private IDockableWindow calendarDockedWindow;
        private List< IDockableWindow > dockedWindows = new List< IDockableWindow >();

        private void GenerateDockableWindows()
        {
            calendarDockedWindow = new CalendarDockedWindow( _inventorApplication ,
                                                             _addInCLSIDString ,
                                                             "MyAddIn:DockedCalendar" ,
                                                             "Calendar" );

            dockedWindows.Add( calendarDockedWindow );
        }
Message 22 of 23
AlexFielder
in reply to: Anonymous

Thanks @Anonymous I'm sure this will come in handy in future!

Message 23 of 23
Anonymous
in reply to: AlexFielder

An additional note, as it was bugging me. I had a few different test windows as proof of concept and some of them the child/hosted WPF Window control was not fully realized, i.e. the control was not maximized in the host panel, or the control's edges were still visible. I tried the form with element host, which worked well in a simple context, but had to resort to using a custom IOTextBox [other source] in order to support actual text entry. The custom control for text entry was a bother, as the WPF hosted Window control handled text entry just fine. So that being said, I found the magic settings for the DockableWindow.AddChild() WPF Host Window for use.

 

The following snippet of code has the design settings for the hosted/child XAML Window Control in a dockable window: [not panel as it is not an activeX device, another time]

 

<Window x:Class="AddIn.Shell.Views.ShellPanelView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="600"
        ResizeMode="NoResize" WindowStyle="None" Visibility="Visible"
        SizeToContent="Manual" WindowState="Maximized">
    <Grid>
    </Grid>
</Window>

The key values were: 

ResizeMode="NoResize" WindowStyle="None" Visibility="Visible" SizeToContent="Manual" WindowState="Maximized"

 That being said, have fun making your own qualified panels. This snippet has been tested up to 2017.. if anything changes I will lookback. Currently, it is working well with a MvVM framework.

 

Best of Luck.

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report