【问题标题】:Is it possible to access resources from a different project using the designer in WinForms?是否可以使用 WinForms 中的设计器访问来自不同项目的资源?
【发布时间】:2013-02-15 22:07:31
【问题描述】:

我有一个相当大的解决方案,其中包含许多项目。理想情况下,我想创建一个 Resources 项目,其中包含我在整个应用程序中需要的所有嵌入式图标。

我已经阅读了人们通过代码引用它们的文章,但是是否可以在设计器中访问该项目的资源?换句话说,我想在设计器中单击表单的 BackgroundImage 属性时选择资源。

如果不是,在尝试将我的资源与我的主项目分离时,我应该考虑哪种架构?每次修改一两行代码时发布一个 100mb 的可执行文件可能不是一个聪明的主意。

【问题讨论】:

    标签: c# winforms resources


    【解决方案1】:

    我找到了一种在多个项目之间共享资源文件并保持 VS Designer 兼容性的工作方式(适用于 VS 2012),这并不复杂:

    1. 在您的源项目中创建一个新的资源文件(在我的示例中命名为 SharedResources.resx

    2. 在 Designer 中打开 SharedResources.resx 并将 Access Modifier 更改为 Public

    3. 使用记事本打开新项目文件的.csproj,并将以下代码添加到包含<compile Include="MyForm.cs"><ItemGroup> 中:(将包括*.resx 和*.Designer.cs 作为链接,无需编译且带有特殊命名空间)

      <EmbeddedResource Include="MY_SOURCE_PROJECT_FOLDER\Properties\SharedResources.resx">
        <Generator>PublicResXFileCodeGenerator</Generator>
        <Link>SharedResources.resx</Link>
        <LastGenOutput>SharedResources.Designer.cs</LastGenOutput>
        <SubType>Designer</SubType>
        <CustomToolNamespace>MY_SOURCE_PROJECT_NAMESPACE.Properties</CustomToolNamespace>
      </EmbeddedResource>
      <None Include="MY_SOURCE_PROJECT_FOLDER\Properties\SharedResources.Designer.cs">
        <AutoGen>True</AutoGen>
        <DependentUpon>SharedResources.resx</DependentUpon>
        <DesignTime>True</DesignTime>
      </None>
      
    4. MY_SOURCE_PROJECT_FOLDER替换为包含资源的项目的相对路径,并将MY_SOURCE_PROJECT_NAMESPACE替换为生成的文件SharedResources.Designer.cs中指定的命名空间(应该是您的全局项目的命名空间)

    5. 享受吧!

    警告:

    有时 VS 在 **.Designer.cs* 共享文件中进行其他自动更改会导致失败,请确保属性 ResourceManager 仍然指向根共享文件。

    重要提示:

    • 在 resx 文件中添加新资源时,请从源项目打开它,否则文件将添加到错误的文件夹中!
    • 刚添加新资源时,如果没有出现在新项目中,只需重启VS,它应该可以工作了

    【讨论】:

    • 使用相对路径(..\projectfolder)与我合作
    【解决方案2】:

    据我所知,您不能在设计器中操作来自其他程序集的资源。仅来自当前项目的那些。

    我会这样做:

    创建一个类库项目。在库中,添加 |新品 |资源文件。将资源(图像、图标)添加到该文件(例如:Resource1.resx)。在该库的类中添加返回资源的公共成员。

    public static class Class1
    {
        public static Bitmap Image1 { get { return Resource1.Image1; } }
        public static Bitmap Image2 { get { return Resource1.Image2; } }
    }
    

    现在在您的项目中引用类库,现在可以在运行时以编程方式设置资源。

    public Form1()
    {
        InitializeComponent();
    
        this.BackgroundImage = ClassLibrary1.Class1.Image1;
    }
    

    但很遗憾,您不能使用设计器。 :( 但是,通过这样做,如果您不对其中的资源进行任何更改,则无需重新分发该 dll。

    【讨论】:

      【解决方案3】:

      我想创建一个包含所有嵌入的资源项目 我在整个应用程序中需要的图标......我想选择 单击窗体的 BackgroundImage 属性时的资源 设计师。

      您可以使用来自另一个程序集的资源但是不幸的是,由于下面解释的原因,您不能通过设计器来做到这一点。

      在您的资源项目中添加一个带有图片框的表单并设置背景图像。这只是为了将图像添加到项目 Resouces.resx 和 Resouces.Designer.cs。将图片添加为资源后,我们可以删除带有图片框的表单。

      在 Resources 项目中,转到 Resouces.Designer.cs 并将类范围更改为 Public,并将图像方法范围从 Internal 更改为 Public:

      public static System.Drawing.Bitmap SO_down {
          get {
              object obj = ResourceManager.GetObject("SO down", resourceCulture);
              return ((System.Drawing.Bitmap)(obj));
          }
      }
      

      在使用资源 DLL 的项目中,您需要将 BackGroundImages 设置为不使用自己的资源:

      之前:

      this.pictureBox1.BackgroundImage = global::WinFormWithSatelliteResources.Properties.Resources.SO_down;
      

      之后:

      this.pictureBox1.BackgroundImage = global::SatResources.Properties.Resources.SO_down;
      

      在尝试解耦我的架构时应该考虑哪种架构 我的主要项目的资源?这可能不是一个聪明的主意 每次我修改一两行代码时,都会发布一个 100mb 的可执行文件。

      如今,大多数企业都乐于依赖互联网。您知道如何对资源进行版本控制,例如 MyStyle22022013.CSS 和 web 浏览器如果他们已经有一个最新的副本就不会获取资源。建议我采取类似的策略,将所有这些图像资源放到网上,这样您就可以更新资源而无需打包和部署它们。

      当你这样想的时候,为什么还要为一个充满资源的程序集烦恼呢?迷宫很好,只是从互联网上提取资源并从文件系统中使用它们。

      如果初始互联网访问(用于下载资源)不是一个选项@jross 答案似乎完全可行。这些天来,虽然我不认为你打算在 CD 上发布这个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-02
        • 2019-04-05
        • 1970-01-01
        • 2016-12-28
        • 1970-01-01
        • 2017-08-03
        • 1970-01-01
        相关资源
        最近更新 更多