Question

I'm developing an add-in for another application, Autodesk Revit, which is built as a separate DLL class library. I'm trying to use the Wpf Tool Kit Property grid in one of my WPF windows. The property grid displays fine in Visual studio, and intellisense works as well. But When I try to start Revit with my add-in loaded I get the following exception.

System.Windows.Markup.XamlParseException occurred
  HResult=-2146233087
  Message=Could not load file or assembly 'Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4' or one of its dependencies. The system cannot find the file specified.
  Source=PresentationFramework
  LineNumber=133
  LinePosition=27
  StackTrace:
       at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
  InnerException: System.IO.FileNotFoundException
       HResult=-2147024894
       Message=Could not load file or assembly 'Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4' or one of its dependencies. The system cannot find the file specified.
       Source=mscorlib
       FileName=Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4
       FusionLog==== Pre-bind state information ===
LOG: User = GLOBAL\eric.anastas
LOG: DisplayName = Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4
 (Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4 | Domain ID: 1
WRN: A partial bind occurs when only part of the assembly display name is provided.
WRN: This might result in the binder loading an incorrect assembly.
WRN: It is recommended to provide a fully specified textual identity for the assembly,
WRN: that consists of the simple name, version, culture, and public key token.
WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
LOG: Appbase = file:///C:/Program Files/Autodesk/Revit 2014/
LOG: Initial PrivatePath = NULL
Calling assembly : PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Program Files\Autodesk\Revit 2014\Revit.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/Xceed.Wpf.Toolkit.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/SDA/bin/Xceed.Wpf.Toolkit.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/SDA/bin/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/Xceed.Wpf.Toolkit.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/SDA/bin/Xceed.Wpf.Toolkit.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit 2014/SDA/bin/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.EXE.

       StackTrace:
            at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
            at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
            at System.Reflection.Assembly.Load(AssemblyName assemblyRef)
            at System.Windows.Baml2006.Baml2006SchemaContext.ResolveAssembly(BamlAssembly bamlAssembly)
            at System.Windows.Baml2006.Baml2006SchemaContext.ResolveBamlTypeToType(BamlType bamlType)
            at System.Windows.Baml2006.Baml2006SchemaContext.ResolveBamlType(BamlType bamlType, Int16 typeId)
            at System.Windows.Baml2006.Baml2006SchemaContext.GetXamlType(Int16 typeId)
            at System.Windows.Baml2006.Baml2006Reader.Process_ElementStart()
            at System.Windows.Baml2006.Baml2006Reader.Process_OneBamlRecord()
            at System.Windows.Baml2006.Baml2006Reader.Process_BamlRecords()
            at System.Windows.Baml2006.Baml2006Reader.Read()
            at System.Windows.Markup.WpfXamlLoader.TransformNodes(XamlReader xamlReader, XamlObjectWriter xamlWriter, Boolean onlyLoadOneNode, Boolean skipJournaledProperties, Boolean shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack`1 stack, IStyleConnector styleConnector)
            at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
       InnerException: 

Typically when I want to reference a 3rd party assembly from a Revit plug-in I simply make sure the 3rd party DLL is being copied to the same location as my plug-in DLL. I checked and Xceed.Wpf.Toolkit.dll is being copied to the directory containing my plug-in DLL.

I noticed from the log messages in the error that it's looking for the DLL in the Revit program directory. After copying Xceed.Wpf.Toolkit.dll into this directory I no longer received the error.

However, I have existing plug-in deployment tools which depend on the plug-in files being in their own isolated folder.

So, does anyone have any idea how I can get the plug-in to find the WPF Toolkit library?

Was it helpful?

Solution

So, I found a new and better solution to this question of mine from 2014.

Today I ran into the same problem where loading a WPF control from an assembly would throw an XamlParseException, except this time it was with a WPF control library assembly that I had created.

I tried moving the DLL into the same folder as the EXE, and as before this solved the problem.

After some searching, I found this question on the telerik.com forums: http://www.telerik.com/forums/xamlparseexception-could-not-load-file-or-assembly

It turns out if you simply give the control a name, by adding a x:Name attribute, this will add a reference to the control in the code-behind and for some reason resolves the issue with loading the assembly.

  <!--This causes a XamlParseException -->
  <mylib:MyCustomControl />

  <!-- This works -->
  <mylib:MyCustomControl x:Name="foobar"/>

OTHER TIPS

I am a fan of this approach. You can register an event on the AppDomain for the AssemblyResolve event, which catches when an assembly cannot be loaded.

It looks like this:

// using System.Reflection and System.IO

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args )
{
    if (args.Name.ToUpper().StartsWith("XCEED.WPF"))
    {
       string asmLocation = Assembly.GetExecutingAssembly().Location;

       string asmName = args.Name.Substring(0, args.Name.IndexOf(','));
       string filename = Path.Combine( asmLocation, asmName );

       if (File.Exists(filename)) return Assembly.LoadFrom(filename);
    }
}

You can make it a little more complete than this, but you get the idea...

I know that this is a very old question but I happened to run across this exact error not too long ago. If your visual studio application uses two projects or a project that references another project, I would check to make sure that BOTH projects have the extended toolkit installed.

Right click on both your projects and click, "Manage NuGet Packages" and then browse on the left hand side of the dialogue to "Installed Packages". If you do not see extended toolkit on both projects then you can use the manager to search online and install them for you.

My issue was that I only had the extended toolkit installed on one project not both.

Hopefully this helps someone out in the future.

Although this has probably been solved, a common reason is failure to add the Xceed.Wpf.Toolkit dll to your entry point project. You probably added it to one of your class libary projects and set its "Copy Local" attribute to true. A reference to this dll also has to be added to your main project which contains your App.xaml.cs with its "Copy Local" attribute set to true.

I am surprised Visual Studio 2013 does not handle this automatically.

While I personally believe you should be doing it as stated in the accepted answer (by @Matt), I would like to mention that copying the dll to the "Program" folder in the Autodesk Revit installation would probably also do the trick. If I recall correctly, they also suggest you deploy your addins to a subfolder of this folder to ensure that it just works. I suspect, that is due to effects like the one you are having.

In the System.Reflection namespace, there is the Assembly class. This can be used to load new assemblies into the current AppDomain.

Assembly.LoadFrom("FileLocation");

Although this is still annoying, I think this might be the only way to have it load a library not in the main directory.

Make sure you "Unblock" the Xceed assembly. Right click on the file and select properties then "Unblock". The VS will compile the code without any errors but when you go to run, Windows will not load the assembly. Mine was even merged into a single assembly.

I used Fody Costura to embedd the Xceed.Wpf.Toolkit.dll in the compiled .dll. Just install it using NuGet and type Install-CleanReferencesTarget into your Packet Manager Console and there you go.

When the control is loaded from the XAML, the calling assembly from which your Xceed.Wpf.Toolkit.dll is loaded is PresentationFramework.dll. So the CLR will not look into your addin folder in this case (what it's doing when another class is loaded from the main assembly of your addin, because it looks into the folder of the calling assembly).

So you can as you've find, put a reference to the control in the code-behind or you can use the AppDomain.CurrentDomain.AssemblyResolve to force the CLR to look in your addin folder.

Putting the dll in the Revit installation folder works, but it's a bad practice in my point of view because it can be overwritten by another addin installation with consequences that are difficult to measure.

I've seen people using this workarounds for Visual Studio Extensions. However VS provides a better solution, using the "ProvideCodeBaseAttribute":

https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.shell.providecodebaseattribute

If you update from 4.3 to 4.4 and you are using .net6, then you get the next error:

Assembly 'Xceed.Wpf.Toolkit' was not found.

In this case you have to change the namespace to

xmlns:tk="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit.NET5"

https://github.com/xceedsoftware/wpftoolkit/issues/1722

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top