在Visual Studio中跨项目共享WinForms资源的问题

Dou*_*las 12 visual-studio-designer winforms

我已将大型多项目解决方案中的所有图像资源移动到专门为共享资源创建的新项目中.

向使用共享映像的其他项目添加新引用正在按预期工作.下面所选按钮中的图像继续出现在设计器中,但有问题.

在VS Designer中,我无法在图像编辑器中选择共享资源,而是手动编辑设计器代码.

更具体地说,在图像编辑器对话框中(从现有控件的"图像"属性访问),我选择"从文件/资源​​中选择..."以弹出"选择资源"对话框(如图所示).在那里,我曾经在访问所有本地项目资源(Resources.resx),我现在想要添加对新共享资源项目的访问权限.理想情况下,我会在显示的下拉列表中添加第二项,切换到共享资源项目的resx.

如何才能做到这一点?有没有更好的办法?

alt text http://permalink.gennetten.com/SharedResourcesIssue.png

cez*_*tko 22

我能够在项目之间共享一个resx文件,并在VS 2008 SP1的设计器中使用它(dunno其他版本).与其他方法不同,这里的资源是静态和动态共享的,因此在运行时实际上只有一份共享资源.没有存储或内存浪费,大量项目易于维护.

按照指南告诉我它是否适合您:

  • 创建一个类项目资源;
  • 创建资源文件(转到属性 - >项目的资源);
  • 将资源文件(默认Resources.resx)移动到项目的根目录 ;
  • 重命名资源文件Resources.resx - > GlobalResources.resx;
  • 将资源文件修饰符修改为Public(双击资源文件,"Access Modifier" - >"Public");
  • 将任何资源文件复制到项目的根目录 ;
  • 使用"添加现有文件"将任何资源添加到资源文件,并在项目的目录中选择资源.

解决方案资源管理器中的项目应如下所示:

在此输入图像描述

现在,在任何项目中,您需要共享resx文件,执行以下操作:

  • 添加"资源"项目作为依赖;
  • 手动编辑项目文件(*.csproj)并在资源文件ItemGroup中添加以下行(如果要查看,则创建本地资源文件):

    <ItemGroup>
      ...
      <EmbeddedResource Include="..\Resources\GlobalResources.resx">
        <Link>GlobalResources.resx</Link>
        <Generator>ResXFileCodeGenerator</Generator>
        <LastGenOutput>GlobalResources.Designer.cs</LastGenOutput>
        <CustomToolNamespace>Resources</CustomToolNamespace>
      </EmbeddedResource>
      ...
    </ItemGroup>
    
    Run Code Online (Sandbox Code Playgroud)

显然,"Include"属性应该是GlobalResources.resx的正确相对路径.

  • 按照您的要求使用设计器中的资源.

在我的项目中,生成以下行并在执行此操作时自动添加到项目中:

<Compile Include="..\Resources\GlobalResources.Designer.cs">
  <Link>GlobalResources.Designer.cs</Link>
  <AutoGen>True</AutoGen>
  <DesignTime>True</DesignTime>
  <DependentUpon>GlobalResources.resx</DependentUpon>
</Compile>
Run Code Online (Sandbox Code Playgroud)

如果未添加,请手动添加.

现在,项目应该在解决方案资源管理器中看起来像这样(likend文件应该标记不同):

在此输入图像描述

最后两个步骤:

  • 单击链接的"GlobalResources.resx",然后在Properties上将"None"设置为"BuildAction"."自定义工具命名空间"应该已经设置为"资源";

在此输入图像描述

  • 单击链接的"GlobalResources.Designer.resx",然后在Properties上将"None"设置为"BuildAction".

在此输入图像描述

您已完成:此时您应该能够使用您在设计器中的共享resx中添加的资源,在您的问题的"项目资源文件"对话框中选择"GlobalResources.resx".而且据说它甚至在运行时也是真的共享!在"属性"面板中,您应该看到外部项目的完整命名空间和类.如果删除对"Resource"项目的依赖性,它甚至不会编译.如果它不适合你,请坚持到它工作,并告诉我哪个指南是错误的.它必须工作!让我知道.


小智 8

我最近遇到了同样的问题.看看MS文档,但找不到任何好的解决方案.我最终能够使WinForms设计器中的图像编辑器使用下面描述的方法识别来自其​​他项目的资源文件.这是hacky - 如果有人有一个更清洁的解决方案,他们想分享请发布.我只在VS 2008上测试了这个.

在开始之前我应该​​说,如果您只想让其他项目可以访问Resources.resx文件中的项目,您可以只编辑其属性并将生成的类的访问修饰符设置为public,以便它使用PublicResXFileCodeGenerator.只有当你想让WinForms设计师在这个资源文件中拾取图像时才需要下面的体操,如Douglas上面的帖子所述.

假设您的解决方案具有以下布局.各种项目的默认命名空间(右键单击解决方案资源管理器中的项目节点 - >属性 - >应用程序选项卡)在这里很重要,所以我在项目名称后面的括号中.

  • MySolution
    • SharedProject(默认名称空间= SharedProject)
      • SharedProject.csproj
    • WinFormsProject1(默认名称空间= WinFormsProject1)
      • WinFormsProject1.csproj
    • WinFormsProject2(默认名称空间= WinFormsProject2)
      • WinFormsProject2.csproj

您想在SharedProject中创建一个资源文件,其中包含WinFormsProject1WinFormsProject2可以使用的图像.

首先在SharedProject的根目录中创建一个新的Resource文件,我们称之为SharedResources.resx.重要的是,此文件使用ResXFileCodeGenerator而不是PublicResXFileCodeGenerator,其原因将在以后变得清晰.

在Visual Studio中编辑SharedResources.resx并添加要共享的图像资源.Visual Studio还应该在SharedProject中为您生成一个名为SharedResources.designer.cs的类文件.

您的解决方案现在应该如下所示:

  • MySolution
    • SharedProject(默认名称空间= SharedProject)
      • SharedProject.csproj
      • SharedResources.resx
      • SharedResources.Designer.cs
    • WinFormsProject1(默认名称空间= WinFormsProject1)
      • WinFormsProject1.csproj
    • WinFormsProject2(默认名称空间= WinFormsProject2)
      • WinFormsProject2.csproj

如果使用文本编辑器打开SharedProject.csproj,您应该看到以下条目:

<EmbeddedResource Include="SharedResources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>SharedResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Compile Include="SharedResources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>SharedResources.resx</DependentUpon>
</Compile>
Run Code Online (Sandbox Code Playgroud)

现在,您需要在WinFormsProject1中访问资源.为此,您需要在文本编辑器中编辑WinFormsProject1.csproj,因为您需要设置的某些属性不会在Visual Studio中公开.

打开WinFormsProject1.csproj文件并在ItemGroup中添加以下内容:

<Compile Include="..\SharedProject\SharedResources.Designer.cs">
    <Link>SharedResources.Designer.cs</Link>
    <AutoGen>True</AutoGen>
    <DesignTime>True</DesignTime>
    <DependentUpon>SharedResources.resx</DependentUpon>
</Compile>
<EmbeddedResource Include="..\SharedProject\SharedResources.resx">
    <Link>SharedResources.resx</Link>
    <Generator>ResXFileCodeGenerator</Generator>
    <LastGenOutput>SharedResources.Designer.cs</LastGenOutput>
    <CustomToolNamespace>SharedProject</CustomToolNamespace>
    <LogicalName>SharedProject.SharedResources.resources</LogicalName>
</EmbeddedResource>
Run Code Online (Sandbox Code Playgroud)

这里的关键是CustomToolNamespaceLogicalName.默认情况下,Visual Studio使用项目的默认命名空间来命名资源并生成*.Designer.cs文件.由于SharedProjectWinFormsProject1具有不同的默认命名空间,因此默认行为会导致嵌入在WinFormsProject1中的资源与SharedProject中的*.Designer.cs文件不兼容.可以通过重写CustomToolNamespace和LogicalName来防止这种情况.

现在对WinFormsProject2.csproj做同样的事情.回到Visual Studio.它会注意到你已经更改了csproj文件并要求重新加载项目 - 选择"重新加载".您应该会发现,在WinFormsProject1WinFormsProject2中设计表单时,您现在可以从SharedResources.resx中选择图像.

基本上什么都的这样是让VS包括SharedResources.resx从文件SharedProjectWinFormsProject1WinFormsProject2项目.只有一个.resx源文件(在SharedProject中),但是当您编译解决方案时,实际上会有三个相同的类,名为SharedProject.SharedResources,三个程序集中的每一个都有一个,但由于它们都具有内部可见性,因此它们不会干涉即使您在项目之间添加引用,也可以相互使用.


小智 6

在VS2012中共享项目之间的资源

仅使用设计师的3个简单步骤!

  1. 创建一个项目并添加您的资源以便像往常一样共享
  2. 创建另一个项目并在"添加现有项目"对话框中"添加为链接"第一个项目的resources.resx,可从上下文菜单访问
  3. 根据需要从链接的资源文件中选择图像; 这可以在"选择资源"对话框的"项目资源文件"下拉菜单中选择,可从属性窗格访问

瞧!