共享带有资源字典(xaml)的项目

5
我正在寻找一种在项目之间共享ResourceDictionary的方法。
向共享项目添加新项不提供资源字典。它可以在其他(主)项目中创建并拖动。但是,然后我无法更改其构建选项为Page

enter image description here

这个想法是像这样加载资源字典

var dictionary = new ResourceDictionary();
dictionary.Source = new Uri("/WpfApplication91;component/Dictionary2.xaml", UriKind.Relative);

目前显然存在问题:

出现了类型为“System.IO.IOException”的异常,位于PresentationFramework.dll中,但未在用户代码中处理

额外信息:无法定位资源“dictionary2.xaml”。

有什么想法吗?

3个回答

4

可以手动编辑共享项目以设置资源字典的生成操作。

共享项目由 Project.shprojProject.projitems 文件组成,打开后者并定位到其中的字典:

<ItemGroup>
  <None Include="$(MSBuildThisFileDirectory)Dictionary.xaml" />
</ItemGroup>

在此之后添加。
<ItemGroup>
  <Page Include="$(MSBuildThisFileDirectory)Dictionary.xaml">
    <Generator>MSBuild:Compile</Generator>
    <SubType>Designer</SubType>
  </Page>
</ItemGroup>

这是一个从普通 csproj 复制/粘贴的内容,用于包含字典的 WPF 项目。

看起来它可以工作,虽然当项目加载到 Visual Studio 中时,此构建操作不可见。将文件添加到共享项目不会影响此手动更改。

现在我可以拥有包含资源字典的共享项目,太棒了!

可以将资源字典合并到应用程序字典中,就像它位于项目根目录一样(在 xaml 设计器中用作静态/动态资源):

<Application.Resources>
    <ResourceDictionary >
        <ResourceDictionary.MergedDictionaries>
            <!-- doesn't really exists in project -->
            <ResourceDictionary Source="Dictionary.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

可以通过此打包 URI手动加载组件和/或程序集:

var dictionary = new ResourceDictionary()
{
     Source = new Uri("pack://application:,,,/FlexProperty.xaml"),
};

3

我遇到了同样的问题。有一个解决方案可以在共享项目中包含 Xaml,而不需要直接编辑 .projitems 文件。

您只需将 Xamarin 添加到您的 Visual Studio 安装中即可(我是通过 VS Community 2015 安装的)。

现在您可以通过常规的 Visual Studio 对话框添加 xaml 类型: 添加资源字典

并且正确的生成操作也会出现: 生成操作

现在共享项目中的 Xaml 可以按预期编译和运行。

(可能是为了支持 Xamarin Forms,但它适用于任何 xaml 文档。)


我添加了一些截图。 - David Oliver
你正在UWP解决方案中使用共享项目。但这并不能解决我的WPF解决方案问题。 - Sinatr
您可以将共享项目添加到任何通常可以添加的项目中,包括 WPF 项目。 - David Oliver
当然可以,但是那里没有“页面”选项的构建选项,请查看问题中的截图,这就是我的问题所在。 - Sinatr
是的,如果您安装了Xamarin,就有这个功能。请看我的截图。我刚刚尝试将共享项目添加到WPF项目中,它可以正常工作。 - David Oliver
我在你的任何截图中都没有看到 WPF 应用程序 ;) - Sinatr

0

这个问题是你在放置应用程序名称,你需要项目名称。以下是如何在XAML和代码中执行的方法

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/SharedProject1;Component/Dictionary2.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

或者

var dictionary = new ResourceDictionary();
dictionary.Source = new Uri("/SharedProject1;component/Dictionary2.xaml", UriKind.Relative);

不,应用程序名称应该可以正常工作。将“Dictionary2.xaml”替换为“Dictionary1.xaml”将使我的代码无问题运行,但我的目标是针对共享项目中的字典。你的更改不应该有任何影响,因为构建操作仍然是“None”。您可以创建相同的项目结构(wpf解决方案,添加共享项目,添加资源字典,将其移动到共享项目中)并将代码放入主窗口构造函数中,以便自行查看。 - Sinatr
你试过我的回复了吗?因为你的非共享项目也是应用程序的名称。 - Bryan
“your none shared project is also the name of the Application” - 我不理解这句话。如果构建操作仍为“无”,则无需尝试任何操作,因为它不起作用。 - Sinatr
在您分享的屏幕截图中,有两个项目,一个是共享的,另一个则不是。您突出显示的语句是指未共享的项目。它与您的解决方案具有相同的名称。因此,即使您输入了解决方案名称,它可能仅查看同名的项目。这也可以解释为什么用Dictionary1.xaml替换Dictionary2.xaml会起作用。 - Bryan
我明白你的意思。我的问题并不是那个,而是构建操作。我提供了使用示例,以展示我的意图,以防有人问:“你为什么要这样做?”-“在任何其他使用此共享项目及其代码的解决方案中都可以像这样使用它”。 - Sinatr

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