MaterialDesignInXamlToolkit: Could not load file or assembly 'MaterialDesignColors, Culture=neutral' or one of its dependencies

Hi am getting the following error when running my class library project.

“Could not load file or assembly ‘MaterialDesignColors, Culture=neutral’ or one of its dependencies. The system cannot find the file specified.”:“MaterialDesignColors, Culture=neutral”} System.Exception {System.IO.FileNotFoundException

I tried the below link forthe issue Could not load file or assembly 'MaterialDesignThemes.Wpf and the issue got fixed by adding the piece of code suggested as below .

   public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
            ShadowAssist.SetShadowDepth(this, ShadowDepth.Depth0);
        }
    }

Is there any fix like above available for `MaterialDesignColors.dll ?

Note : All the dlls exists in same folder.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 6
  • Comments: 39 (12 by maintainers)

Most upvoted comments

For folks still encountering this issue: this post by Carlos Anderson explains what’s going on:

There’s another tricky thing. Because you don’t use any classes in the Material Design assemblies, your script assembly doesn’t load those assemblies. It’s the XAML parser that uses the Material Design assemblies and therefore tries to load them. The problem is that, because it’s not your assembly that loads them, .NET looks for the Material Design assemblies in the wrong place.

And provides a solution similar to what @z3ke1r suggests:

public MainWindow()
{
    InitializeMaterialDesign();
    InitializeComponent();
}
 
private void InitializeMaterialDesign()
{
    // Create dummy objects to force the MaterialDesign assemblies to be loaded
    // from this assembly, which causes the MaterialDesign assemblies to be searched
    // relative to this assembly's path. Otherwise, the MaterialDesign assemblies
    // are searched relative to Eclipse's path, so they're not found.
    var card = new Card();
    var hue = new Hue("Dummy", Colors.Black, Colors.White);
}

This solved it for me.

Hi, I encountered the same issue while attempting to load an application. I built upon @hedinjke’s good work by removing unnecessary calls to the Assembly.LoadFrom() method. I noticed that your suggestion would lead to many unnecessary calls - in my case, the same assembly would be loaded 16 times or so.

Instead of using a foreachstructure to iterate over the list of assemblies returned by:

var assemblies = from file in dir.EnumerateFiles()
    where file.Name.EndsWith(".dll") ||
    file.Name.EndsWith(".exe")
    select Assembly.LoadFrom(file.FullName);

I return a list of strings and use LINQ expressions to compare between the assemblies already loaded, and the ones required by the AppDomain.CurrentDomain.AssemblyResolve event.

  • If the assembly is already loaded, we return it, as expected by the event
  • If the assembly is not loaded, and requested and present in the list of files, we return it via return Assembly.LoadFrom(assemblyToLoad);
  • If the assembly is not loaded, and requested, but missing from the build directory, we return null.

AssemblyLoader.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;

namespace App.Namespace
{
    /// <summary>
    /// Used to determine the UNC path of the solution files (on the file system)
    /// and load the assembly
    /// </summary>
    public class AssemblyLoader : IDisposable
    {
        private static string _executingPath;
        public AssemblyName _assemblyName;

        private DirectoryInfo _fileInfo;
        private IEnumerable<string> _assemblies;

        readonly AppDomain currentDomain = AppDomain.CurrentDomain;

        private IEnumerable<Assembly> _domainAssemblies;

        /// <summary>
        /// Default constructor
        /// </summary>
        public AssemblyLoader()
        {
            // Store the loaded assemblies
            _executingPath = Assembly.GetExecutingAssembly().Location;
            _fileInfo = new FileInfo(_executingPath).Directory;

            // Return a list of all DLLS from the executing directory
            _assemblies = EnumerateFiles.GetFiles(_fileInfo);
            _domainAssemblies = currentDomain.GetAssemblies().Where(a => !a.IsDynamic);

            AppDomain.CurrentDomain.AssemblyResolve += LoadApplicationAssemblies;
        }

        /// <summary>
        /// Event handler to return an assembly
        /// </summary>
        /// <param name="sender">The object that raises the event</param>
        /// <param name="args">Supplementary parameters</param>
        /// <returns>The name of the a assembly</returns>
        public Assembly LoadApplicationAssemblies(object sender, ResolveEventArgs args)
        {
            if (string.IsNullOrEmpty(_executingPath))
                return null;

            try
            {
                // Ignore missing resources
                if (args.Name.Contains(".resources"))
                    return null;

                // Check for assemblies already loaded
                Assembly loadedAssembly = _domainAssemblies.FirstOrDefault(x => x.FullName == args.Name);
                if (loadedAssembly != null)
                    return loadedAssembly;

                var requestedAssembly = args.Name.Split(',')[0];
                var assemblyToLoad = _assemblies.Where(x => x.Contains(requestedAssembly)).FirstOrDefault();

                return Assembly.LoadFrom(assemblyToLoad);
            }

            catch (Exception e)
            {
                // or rethrow the exception
                // throw;
                return null;
            }
        }

        public void Dispose()
        {
            AppDomain.CurrentDomain.AssemblyResolve -= LoadApplicationAssemblies;
        }
    }
}

EnumerateFiles.cs

using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace App.Namespace
{
    /// <summary>
    /// Return a list of DLLs in-use by the project. See the <see cref=AssemblyLoader"/> class
    /// for an example
    /// </summary>
    class EnumerateFiles
    {
        /// <summary>
        /// Return the list of files in fileInfo
        /// </summary>
        /// <param name="fileInfo">The directory</param>
        /// <returns>A read-only enumerable (list) that contains a list of files in use</returns>
        public static IEnumerable<string> GetFiles(DirectoryInfo fileInfo)
        {
            return from file in fileInfo.EnumerateFiles()
                   where (file.Name.EndsWith(".dll") || file.Name.EndsWith(".exe"))
                   select file.FullName;
        }
    }
}

Finally found solution.

May be this gonna help someone. Here is it:

public class AssemblyLoader: IDisposable {
 private static string ExecutingPath => Assembly.GetExecutingAssembly().Location;

 public AssemblyLoader() {
  AppDomain.CurrentDomain.AssemblyResolve += LoadMaterialDesign;
 }

 private static Assembly LoadMaterialDesign(object sender, ResolveEventArgs args) {
  if (null == ExecutingPath) return null;
  string assemlyToLoad = string.Empty;

  string GetAssemblyName(string fullName) => fullName.Substring(0, fullName.IndexOf(','));

  var path = ExecutingPath;
  var dir = new FileInfo(path).Directory;

  var assemblies = from file in dir.EnumerateFiles()
  where file.Name.EndsWith(".dll") ||
   file.Name.EndsWith(".exe")
  select Assembly.LoadFrom(file.FullName);

  foreach(var assembly in assemblies) {

   var assemName = GetAssemblyName(assembly.FullName);
   var requested = GetAssemblyName(args.Name);

   try {
    if (assemName == requested) {
     return assembly;
    }
   } catch (Exception) {
    continue;
   }

   //}
  }
  return null;
 }

 void IDisposable.Dispose() {
  AppDomain.CurrentDomain.AssemblyResolve -= LoadMaterialDesign;
 }
}

Usage example:

[Transaction(TransactionMode.Manual)]
public class Command : IExternalCommand
{
	public Result Execute(ExternalCommandData commandData,
						ref string message,
						ElementSet elements)
	{
		using var loader = new AssemblyLoader();
                /// Your command implementation
		return Result.Succeeded();
	}
}

For anyone using this library in a Visual Studio extension, you have to do two things:

  1. Sign the assembly (necessary for all VSIX dependencies). The easiest way is using the StrongNamer package. Just add it to your project as a reference and it will sign all unsigned dependencies at build time. No further setup needed.
  2. Add the [ProvideBindingPath] attribute to extension’s Package or AsyncPackage file. This tells your XAML files to look at all the project’s references. See here for more details.

@Arshad8464 @Keboo Solving it was pretty simple. Just Install MaterialDesignColors over NuGet as well

@Keboo Yes, I have isolated further to the pure WPF version. In this stage, it should reproduce the issue. In App.xaml I have left lines to comment out. If you do so comobox is working. Thanks for having a look. https://github.com/DesignboticTeam/MaterialDesignBug

Since it’s a reference error, i checked to see what could be a possible solution.

All i did was:

Right click your project Select Add --> Reference

In the menu Assemblies make sure Accessibility is activated.

That’s it, everything is working.

@Keboo i apologise for my late response. My second post was only one of many quick&dirty ways i tried in order to solve the problem, i should have posted the code that covers loading MatreialDesignColors as well (yet the error message would have been the same). What solved my problem was completely abendoning the code snipped from my second post and doing what @Arshad8464 and @z3ke1r did. I didn’t originally understand that this approach would solve the problem, because i was trying to follow MVVM pattern and keep code behind clean. Therefore it didn’t make any sense to me that they were suggesting to put bullshit code in the file that i was trying to keep empty. But hey, it works now! 😃

I had the same error. I used the shadow assist code above for the ‘MD Themes’ and used the code below to get the ‘Colors’.

var hue = new Hue("Dummy", Colors.AliceBlue, Colors.AntiqueWhite);