How to add resources properly in Visual Studio 2022?

Just started using Visual Studio Community 2022. Couldn’t understand how to add resources properly.

Now it seems to be all handled by this .resx and after I added my resource there, I still don’t see autocomplete showing this Properties.Resources.Ghtml, which is how i would call the resource in old version of visual studio

EDIT: after some Google searches, I’ve found a less elegant workaround. Not sure if by using Reflection it impacts performance

Your issue is likely because of the Project type, not directly related to your version of Visual Studio.

The new project types introduced for .Net Core projects moved away from the traditional Resources file.

You can probably manually edit the .csproj file to enable compilation of the resx file, try adding this to your project file:

  <ItemGroup>
    <Compile Include="Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <SubType>Designer</SubType>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </ItemGroup>

Then just copy a resx file from an old project. There is probably a less manual way to adding the legacy resx to a new project.

1 Like

I also had a problem adding icons in the latest versions of Visual Studio. When I double-click the .resx file VS opens the new interface of the Resource Explorer. And all the images added through this new interface have the wrong path to the Resource folder.

The workaround is to open the .resx file with the legacy Resource Editor: right-click - Open with... - Managed Resources Editor. Images added with the legacy one have the right path.

In addition to using resource files, you can directly embed your icon as an embedded resource. Here’s how:

  1. Add the Image to Your Project:
  • In Solution Explorer, right-click on your project, then select Add > Existing Item….
  • Navigate to the image file (e.g., spiral.png), select it, and click Add.
  1. Set the Build Action:
  • In Solution Explorer, locate the added image file.
  • Right-click on the file, select Properties, and set the Build Action property to Embedded Resource.
  1. Retrieve and Use the Embedded Resource:
  • Add the following code to your plugin to retrieve the embedded image and use it as the icon:
protected override Bitmap Icon
{
    get
    {
        using (var stream = Assembly.GetExecutingAssembly()
                   .GetManifestResourceStream("MyGrasshopperAssembly1.spiral.png"))
        {
            return stream != null ? new Bitmap(stream) : null;
        }
    }
}
  • The full resource name must include the namespace and folder path. For example, if spiral.png is in a folder called Resources, the resource name would be:
"MyGrasshopperAssembly1.Resources.spiral.png"

4 Likes

Thanks! This method is similar to what was linked in my OP.
Would you say doing so through System.Reflection would have performance penalties?
I honestly have no idea. Something about calling Properties.Resources.Filename seems faster than GetExecutingAssembly() and look for it.

I would say using resource files is slightly faster because it relies on strongly-typed resource accessors, which avoid the reflection overhead of GetManifestResourceStream. However, as far as I understand, using direct embedding is a more standard approach in .NET Core. In fact, it seems that Grasshopper2 icons are implemented using direct embedding.

I don’t have an old .resx to copy. Starting a new project and trying to add resources that I can call with the “.” in-line

Drop this file in your project, you may need to modify your .csproj file, but you may also be able to just show external files in Solution Explorer, and then right click on this file and choose “Include in Project”.
Resources.zip (1.5 KB)

I see what you mean now. It’s necessary to use an old .resx in this case, even if it’s a placeholder.

1 Like