Я пытаюсь использовать MaterialDesignXamlToolkit в своей библиотеке классов WPF (инфраструктура .NET). Я следую их официальному учебник по быстрому старту, но поскольку у меня нет App.xaml, мне пришлось внести некоторые коррективы. Видимо какой-то шаг был неправильным, но я не знаю какой.
1) Я установил MaterialDesignXamlToolkit с помощью Nuget.
2) Я создал ResourceDictionary со следующим кодом: (я указал ключ, потому что если я этого не сделаю, возникнет ошибка)
<ResourceDictionary xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary x:Key = "123">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source = "pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source = "pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source = "pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
<ResourceDictionary Source = "pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ResourceDictionary>
Если я удаляю элемент <ResourceDictionary x:Key = "123">
, я получаю сообщение об ошибке:
System.Windows.Markup.XamlParseException: Set property 'System.Windows.ResourceDictionary.Source' threw an exception.
FileNotFoundException: Could not load file or assembly 'MaterialDesignThemes.Wpf, Culture=neutral' or one of its dependencies.
3) Мой «главный экран» — это страница, поэтому я добавил на нее ресурс:
<Page.Resources>
<ResourceDictionary Source = "/MyAsembly;component/ResourceDictionary/MaterialDesign.xaml" />
</Page.Resources>
4) Здесь возникает очевидная проблема (это второй шаг официального руководства): я добавляю следующий код на свою страницу:
<Page ...
xmlns:materialDesign = "http://materialdesigninxaml.net/winfx/xaml/themes"
TextElement.Foreground = "{DynamicResource MaterialDesignBody}"
TextElement.FontWeight = "Regular"
TextElement.FontSize = "13"
TextOptions.TextFormattingMode = "Ideal"
TextOptions.TextRenderingMode = "Auto"
Background = "{DynamicResource MaterialDesignPaper}"
FontFamily = "{DynamicResource MaterialDesignFont}">
Но я получаю предупреждение, что: The resource {MaterialDesignBody, MaterialDesignPaper, MaterialDesignFont} could not be resolved.
Некоторые из решений, которые я пробовал, указывали на то, что действие сборки ResourceDictionary должно быть страницей, и это так.
Любая помощь будет принята с благодарностью!
Для начала удалите элемент <ResourceDictionary x:Key = "123">
из ResourceDictionary
:
<ResourceDictionary xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source = "pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source = "pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source = "pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
<ResourceDictionary Source = "pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Затем вы сможете установить свойства, используя синтаксис элемента свойства после, который вы установили для свойства Resources
:
<Page ...
d:DesignHeight = "450" d:DesignWidth = "800">
<Page.Resources>
<ResourceDictionary Source = "/MyAsembly;component/ResourceDictionary/MaterialDesign.xaml" />
</Page.Resources>
<Page.Background>
<DynamicResource ResourceKey = "MaterialDesignPaper" />
</Page.Background>
</Page>
Когда я делаю так, как говорит первый фрагмент кода, я все равно получаю сообщение об ошибке, упомянутое в моем вопросе: FileNotFoundException: Could not load file or assembly 'MaterialDesignThemes.Wpf, Culture=neutral' or one of its dependencies.
. Я полагаю, что код ломается, прежде чем он достигает второго фрагмента кода.
@MarijaRakic: Значит, вы неправильно установили пакет NuGet. Вам нужно сослаться на сборку MaterialDesignThemes.Wpf
.
Проблема может заключаться в приложении, для которого я создаю плагин (как я уже упоминал, мой проект представляет собой библиотеку классов). Я буду продолжать расследование и вернусь к предложенному вами решению.
Теперь, когда я решил проблему, я понимаю, что в моем вопросе отсутствует одна важная информация: я следовал шаблону MVVM (поэтому весь мой код за файлами был пуст).
Проблема заключалась в том, что Revit (приложение, для которого я создавал плагин) загружает библиотеки, которые использует плагин. Я до сих пор не понимаю внутренней логики этого, но следующие две строки, добавленные в код первой загружаемой страницы, решили проблему для меня:
ColorZoneAssist.SetMode(new GroupBox(), ColorZoneMode.Accent);
Hue hue = new Hue("name", System.Windows.Media.Color.FromArgb(1, 2, 3, 4), System.Windows.Media.Color.FromArgb(1, 5, 6, 7));
Я не могу не подчеркнуть, что эти две строки кода — полная ерунда (поскольку я не хочу размещать какую-либо логику в коде), но в противном случае библиотеки не будут загружены. Этот код каким-то образом «заставляет» Revit загружать библиотеки дизайна материалов (1-я строка кода использует MaterialDesignTheme.Wpf и 2-я MaterialDesignColors), поскольку (я полагаю) он уже может сказать во время компиляции, что эти библиотеки необходимы.
Это сработало для меня в проекте VSIX.
Без добавления этих строк. Дважды проверьте, копируется ли DLL-файл MaterialDesign в выходной путь приложения.
Я видел такую проблему раньше, просто добавляя бессмысленный код, и Visual Studio понимает, что ваше приложение, которое зависит от вашей библиотеки, также зависит от библиотеки MaterialDesign, а затем снова копирует dll, как и следовало ожидать в первую очередь.
Вместо добавления этих строк вы могли бы затем
Эти файлы определенно присутствуют в папке отладки, в том же месте, где собрана моя библиотека. Не могли бы вы пояснить шаги 1 и 2? Если я добавлю using MaterialDesignThemes.Wpf; using MaterialDesignColors;
, но никогда не использую в коде, эти операторы include будут игнорироваться при компиляции проекта.
У меня работал принятое решение. Однако, чтобы избежать фиктивного кода, я также смог заставить MDXT работать, добавив следующее в код программной части словаря ресурсов:
Assembly.LoadFrom(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MaterialDesignThemes.Wpf.dll"));
Assembly.LoadFrom(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MaterialDesignColors.dll"));
Не могли бы вы показать, где именно вы поместили их в свой программный код и какие операторы использования были необходимы? Intellisense не очень хорошо помогает здесь.
@fix с помощью System.IO и System.Reflection. Эти строки должны находиться в конструкторе кода программной части или в любом другом месте, где они будут выполняться до того, как что-либо попытается отобразить Xaml.
@ mm8, пожалуйста, проверьте мой отредактированный вопрос.