从另一个程序集

时间:2016-03-18 14:00:43

标签: c# .net wpf xaml resourcedictionary

好的,我现在已经几个小时不知所措了,仍然无法找到解决方案。

首先,我将解释我创建的简单测试用例: 溶液

- ClassLibrary1
  - Dictionary1.xaml
- WpfApplication3
  - App.config
  - App.xaml
  - Dictionary2.xaml
  - MainWindows.xaml

ClassLibrary1的:

该项目具有必要的引用,允许我添加wpf-dictionary:
PresentationCore,PresentationFramework,Systam.Xaml,windowsbase
(以及任何常规类库的所有标准程序集)

这是Dictionary1.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Color x:Key="PrimaryBackgroundColor">#FF030010</Color>
    <SolidColorBrush x:Key="PrimaryBackgroundBrush" Color="{StaticResource PrimaryBackgroundColor}" />
</ResourceDictionary>

WpfApplication3:

这个项目只是在wpf-form上显示一个按钮。

Dictionary2.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:WpfApplication3">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/ClassLibrary1.dll;component/Dictionary1.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    <Style TargetType="Button">
        <Setter Property="Background" Value="{StaticResource PrimaryBackgroundBrush}" />
    </Style>
</ResourceDictionary>

MainWindow.xaml

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication3"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary2.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Button Content="aaa" Width="100" Height="40" />
    </Grid>
</Window>

这一切 - 很简单,你可以看到 这里唯一的事情是dictionary2需要使用来自dictionary1的资源。

因此有两种方法可以引用另一个程序集:

选项1: 类库是解决方案中的一个项目,您的WpfApplication添加了对同一解决方案中的类库项目的引用。这是通过Add-Reference / Projects完成的,在这种情况下一切都很好。

选项2: 类库不是您的解决方案。 (实际上它可以像我的例子) 但是,您可以通过添加对ClassLibrary1.Dll的引用来添加引用,该引用位于您的 bin\debugbin\release个文件夹。 在那种情况下,打开地狱之门。 Dictionary2抱怨它无法找到资源&#39; PrimaryBackgroungBrush&#39;并在执行时粉碎 抱怨它找不到dictionary1.xaml

抛出异常:&#39; System.Windows.Markup.XamlParseException&#39;在PresentationFramework.dll中 和内在的例外: {&#34;无法加载文件或程序集&#39; ClassLibrary1.dll,Culture = neutral&#39;或其中一个依赖项。 系统找不到指定的文件。&#34;:&#34; ClassLibrary1.dll,Culture = neutral&#34;}

问题是使用option2是必不可少的,因为我想在没有其他wpf项目的情况下共享相同的字典 将ClassLibrary1项目作为其解决方案的一部分。

建议的复制方式:

  1. 在Visual Studio中为WPF应用程序创建一个新的解决方案。
  2. 将类库项目添加到解决方案中。
  3. 在类libarary项目中,添加对以下程序集的引用:PresentationCore,PresentationFramework,Systam.Xaml,windowsbase
  4. 添加Wpf-Dictionary&#39; Dictionary1&#39;到您的类库项目并复制代码。 (您可以从wpf项目中复制一个,因为它不会作为类库中添加项的选项存在)
  5. 添加Wpf-Dictionary&#39; Dictionary2&#39;到您的wpf应用程序并复制代码。
  6. 复制MainWindow的代码。
  7. 现在:

    1. 添加对类库的引用(作为项目,从“添加引用”对话框的“项目”选项卡) 建立一切 - 一切都应该有效。

    2. 删除对类库的引用。
      添加对类库的引用(作为dll,从浏览选项卡中找到它,并在classlibrary / bin / debug或release文件夹中找到它) 建立一切 - 你会注意到我的问题。

    3. 解决这个问题的方法是什么?

      更新1

      我更改了dictionary2.xaml中的行:
        <ResourceDictionary Source="pack://application:,,,/ClassLibrary1.dll;component/Dictionary1.xaml"/>
      要:
        <ResourceDictionary Source="pack://application:,,,/ClassLibrary1;component/Dictionary1.xaml"/>

      现在项目编译并执行时没有错误,但是在设计时 - dictionary2的xaml视图表明它无法找到资源:&#39; PrimaryBackgroundBrush`并在下面放置丑陋的卷曲下划线它。
      这是一个进步 - 但我仍然不满意。
      任何想法如何解决?

      更新2 如前所述 - 现在一切都在编译和执行 但是你在下面的图片中看到的东西让我很烦恼,
      我只是想确定那些将类库添加为.Dll文件而不是项目的人100%确定他们没有得到可以在图片中看到的问题,这意味着他们的xaml intellisense可以识别资源设计时间。 the error I see

1 个答案:

答案 0 :(得分:1)

我可以想象关于该dll的文档将如何:

  •   

    项目中的参考dll

  •   

    将其添加到项目中的资源字典中:

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="pack://application:,,,/ClassLibrary1.dll;component/Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
  •   

    将此添加到每个窗口/ usercontrol:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Dictionary2.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

看起来很神秘。

如何在库中创建必须由每个窗口/用户控件引用的管理器,它会自动执行哪些操作?

这是我在评论中提到的主题管理器的剪辑(它自动合并),考虑易于使用。

xaml(将此添加到每个窗口/ usercontrol,它必须支持设计/运行时的主题切换):

         local:Theme.Theme=""

cs(这部分必须是图书馆的一部分):

public static class Theme
{
    public static readonly DependencyProperty ThemeProperty =
        DependencyProperty.RegisterAttached("Theme", typeof(string), typeof(Theme), new PropertyMetadata(null, (d, e) =>
        {
            var theme = (string)e.NewValue;
            // in run-time set theme to specified during init
            if (!DesignerProperties.GetIsInDesignMode(d))
                theme = _theme;
            var element = d as FrameworkElement;
            element.Resources.MergedDictionaries.Clear();
            if (!string.IsNullOrEmpty(theme))
            {
                var uri = new Uri($"/MyPorject;component/Themes/{theme}.xaml", UriKind.Relative);
                element.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = uri });
            }
        }));
    public static string GetTheme(DependencyObject obj) => (string)obj.GetValue(ThemeProperty);
    public static void SetTheme(DependencyObject obj, string value) => obj.SetValue(ThemeProperty, value);

    static string _theme = "Generic";

    static string[] _themes = new[]
    {
        "Test",
    };

    /// <summary>
    /// Init themes
    /// </summary>
    /// <param name="theme">Theme to use</param>
    public static void Init(string theme)
    {
        if (_themes.Contains(theme))
            _theme = theme;
    }
}

P.S。:功能是原始的(在我的情况下已足够),但应该给你一个想法。