Error WPF loading Revit 2025: Revit Module
Hi @Nice3point
- There is bug with Dependencies Isolate mechanism in Revit 2025, the others version work fine
- I have already test on your sample project
MultiProjectApplication- Can not execute the command with
WPFimplementation - Work fine if using
IExternalCommandinstead ofExternalCommand - The other sample
MultiProjectSolutionwork fine with Dependency Injection
- Can not execute the command with
- Can you explain me, why I got this error and way to fix it? Thank you
@trgiangv Hi, good question
This is a WPF problem at the moment
https://github.com/dotnet/wpf/issues/1700
The thing is that WPF uses the first found assembly and its context instead of the one allocated for the plugin. And if the context is different, an exception is thrown on this line:
https://github.com/dotnet/wpf/blob/7b9ea813382f4543474dc42e5dd92b28ef753c48/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs#L463
I investigated the problem and found that Module1 is loaded 2 times, in Default context and AddinContext, which throws an exception.
However, this can be fixed, just avoid loading the dependency when binding the command to the Revit ribbon. Move ExternalCommands from modules to the project containing ExternalApplication. This will prevent preloading the dependency (similar to DI) and load it only in the AddinContext, avoiding the Default.
And now it works:
Thanks for discovering it, I'll update the examples with this workaround, and wait for Microsoft to fix WPF
Thank you for clarifying the issue @Nice3point
I just came across this as well when registering a dockable window. Do you happen to have any useful tips for how to handle this situation?
@russgreen
Works fine for me. Can you share your sample? Try to use DockablePaneProvider
https://github.com/user-attachments/assets/ba276ea3-3eda-40e7-861f-05a06d275c27
To be fair I was still using IDockablePaneProvider to register the panel. Completely missed that you have the DockablePanelProvider. Also now tried this and my issue still occured. My addin is fine. Loads up OK and works but then I click on a command in DiRoots.One. I was getting this error.
Error Name: XamlParseException
Full Name: System.Windows.Markup.XamlParseException
Inner Exception: [A]Microsoft.Xaml.Behaviors.InvokeCommandAction cannot be cast to [B]Microsoft.Xaml.Behaviors.InvokeCommandAction. Type A originates from 'Microsoft.Xaml.Behaviors, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' in the context '"Debug R25" Nice3point.Revit.Toolkit.Helpers.AddinLoadContext #6' at location 'D:\Development\Source\Repos\RevitResourceLibrary\source\RRL.Addin\bin\Debug R25\Microsoft.Xaml.Behaviors.dll'. Type B originates from 'Microsoft.Xaml.Behaviors, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' in the context 'Default' at location 'C:\Program Files\Autodesk\Revit 2025\Microsoft.Xaml.Behaviors.dll'.
Exception: Set connectionId threw an exception.
OS Version: Microsoft Windows NT 10.0.22635.0
But norrowed it down. What I've found in the past is if I need to use Xaml.Behaviors in an addin Window I would sometimes get 'Could not load file or assembly 'Microsoft.Xaml.Behaviors' (https://github.com/microsoft/XamlBehaviorsWpf/issues/86) unless I add this line to the view constructor. If I disable this I don't get the error with DiRoots.
public partial class MainView : Page
{
public MainView()
{
InitializeComponent();
//enable this line of code if XAML Behaviors is used
//var _ = new Microsoft.Xaml.Behaviors.DefaultTriggerAttribute(typeof(Trigger), typeof(Microsoft.Xaml.Behaviors.TriggerBase), null);
}
}
I've commented out this line and disabled all other addins but cannot reproduce the old Xaml problem now either. I can find a workaround to XAML interaction logic in this panel so will do that instead.
The found way from @CG-KhalidFathy if moving ExternalCommands didn't help https://github.com/Nice3point/RevitTemplates/issues/57
the problem gets more complicated when using external UI libraries like material design toolkit or mah app even the suggested way of LoadViewFromUri might not work for all cases! i think if we can provide a way to use the old way of assembly resolver instead of AddinContext might solve these issues till Microsoft solve the issue of wpf xml parser
Same issue here with a twist, with a specific plugin(AVAIL 5.2.3) installed I was actually able to reproduce this error on the newest updated multiple project solution sample as well. So far I haven't found anything special about AVAIL beside it also referenced Microsoft.extension.DI (8.0.0), but its seems to be triggering this dependency loading context error in 2025. Without AVAIL dependency isolation appears to work as intended, no duplicating module when checked using Revit lookup.
For the moment I am partially navigating around this issue with the fix by @CG-KhalidFathy Here is a modified version that dynamically find the xaml path when used in the code behind
public static class IsolatedViewLoader
{
// Used to sidestep issue in https://github.com/Nice3point/RevitToolkit/issues/7
public static void LoadViewFromUri(this FrameworkElement view, string baseUri)
{
var resourceLocater = new Uri(baseUri, UriKind.Relative);
var exprCa = (PackagePart)typeof(Application).GetMethod("GetResourceOrContentPart", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { resourceLocater });
var stream = exprCa.GetStream();
var uri = new Uri((Uri)typeof(BaseUriHelper).GetProperty("PackAppBaseUri", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null, null), resourceLocater);
var parserContext = new ParserContext
{
BaseUri = uri
};
typeof(XamlReader).GetMethod("LoadBaml", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { stream, parserContext, view, true });
}
// Utility method to dynamically determine the URI for the XAML file and load it
public static void LoadView<T>(this T view) where T : FrameworkElement
{
var uri = GetXamlUri(view.GetType());
view.LoadViewFromUri(uri);
}
// Method to dynamically determine the URI for the XAML file based on the class name and namespace
private static string GetXamlUri(Type viewType)
{
var assemblyName = viewType.Assembly.GetName().Name;
var namespaceName = viewType.Namespace;
var className = viewType.Name;
var xamlFileName = className + ".xaml";
// Remove the first level of the namespace
var namespaceParts = namespaceName.Split('.');
var adjustedNamespace = string.Join("/", namespaceParts, 1, namespaceParts.Length - 1);
var uri = $"/{assemblyName};component/{adjustedNamespace}/{xamlFileName}";
return uri;
}
}