如何将MaterialDesignXamlToolkit添加到WPF类库中?

3
我正在尝试在我的WPF类库(.NET框架)中使用MaterialDesignXamlToolkit。我正在遵循他们官方的快速入门教程,但由于我没有App.xaml文件,所以我必须进行一些调整。显然某个步骤出错了,但我不知道是哪一个。
1)我使用Nuget安装了MaterialDesignXamlToolkit。
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}">

但我收到一个警告: 无法解析资源{MaterialDesignBody,MaterialDesignPaper,MaterialDesignFont}。

我尝试了一些解决方案,指出ResourceDictionary的构建操作应该是页面,并且它确实是。

任何帮助都将不胜感激!


@mm8请检查我编辑过的问题。 - Marija Rakic
请问您能否给我展示一下MaterialDesign和mainscreen的xaml和cs文件?另外,我能看一下您是如何显示主屏幕的吗?我只找到了使用form.ShowDialog()来显示窗口的方法,但我找不到任何显示页面的方法... - JanSmutný
5个回答

4

这个被接受的解决方案对我有用。然而,为了避免虚拟代码,我还能通过将以下内容添加到资源字典的代码后端来实现MDXT工作:

Assembly.LoadFrom(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MaterialDesignThemes.Wpf.dll"));
Assembly.LoadFrom(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MaterialDesignColors.dll"));

您介意展示一下这些代码放在哪里,需要哪些using语句吗?Intellisense在这里并没有提供很好的帮助。 - fix
1
请使用System.IO和System.Reflection修复代码。这些行应该放在代码后台的构造函数中,或者任何在尝试显示Xaml之前运行它们的地方。 - Trygve

3
现在我已经解决了这个问题,意识到我的问题缺少一个重要的信息:我正在遵循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加载Material Design库(第一行使用MaterialDesignTheme.Wpf,第二行使用MaterialDesignColors),因为(我认为)编译时已经可以确定需要这些库。


这对我在VSIX项目中起作用。 - fix

2

首先从您的ResourceDictionary中删除<ResourceDictionary x:Key="123">元素:

<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. 我相信代码在达到第二个代码片段之前就已经出现了错误。 - Marija Rakic
@MarijaRakic:那么你没有正确安装NuGet包。你需要引用MaterialDesignThemes.Wpf程序集。 - mm8
问题可能出在我正在为其构建插件的应用程序上(正如我所提到的,我的项目是一个类库)。我会进一步调查并回到您提出的解决方案。 - Marija Rakic

0

这个评论对我解决了问题,但是请确保你没有其他错误,如果有,请找到并修复它们,然后尝试运行项目,它就会正常工作。

using MaterialDesignColors;
using MaterialDesignThemes.Wpf;

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);
}

0

不要添加这些行。请仔细检查MaterialDesign dll文件是否已复制到应用程序的输出路径。

我以前见过这样的问题,只需添加无意义的代码,Visual Studio就会意识到您的应用程序依赖于您的库,也依赖于MaterialDesign库,然后再次将dll复制,就像最初期望的那样。

而不是添加这些行,您可以:

  1. 直接在应用程序中引用MaterialDesign
  2. 使用构建事件确保将DLL复制到构建路径。

这些文件肯定存在于调试文件夹中,就在我的库构建的同一位置。您能澄清步骤1和步骤2吗?如果我添加了 using MaterialDesignThemes.Wpf; using MaterialDesignColors;,但从未在代码中使用过,那么这些包含语句将在编译项目时被忽略。 - Marija Rakic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接