Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows Forms Designer Copies Global Project Resource Image to Form Resource File #3958

Closed
ab-tools opened this issue Sep 19, 2020 · 34 comments
Assignees
Labels
area-VSDesigner Windows Forms out-of-proc designer related issues 💥 regression-preview Regression from a preview release
Milestone

Comments

@ab-tools
Copy link

ab-tools commented Sep 19, 2020

  • .NET Core Version:
    .NET 5.0-rc1 using Visual Studio 16.8.0 Preview 3.0.

  • Have you experienced this same bug with .NET Framework?:
    No.

Problem description:
Assigning a project image resource e. g. to the Image property of a button using the Windows Forms Designer results in copying the corresponding resource file from the global project resources to the local form resource and adding following line in the designer code file:
this.InOK.Image = ((System.Drawing.Image)(resources.GetObject("InOK.Image")));

Expected behavior:
The global resource should be used directly as it was the case previously in the .NET Framework. The expected line in the designer code should be similar to this:
this.InOK.Image = global::QuickArchive.Properties.Resources.ok_16;

@ab-tools ab-tools changed the title Windows Forms Designer Copies Global Resource to Forms Resource File Windows Forms Designer Copies Global Resource to Form Resource File Sep 19, 2020
@ab-tools ab-tools changed the title Windows Forms Designer Copies Global Resource to Form Resource File Windows Forms Designer Copies Global Project Resource Image to Form Resource File Sep 19, 2020
@kirsan31
Copy link
Contributor

We faced this behavior too, but not 100% of the time and we could not understand the conditions under which this occurs.

@ab-tools
Copy link
Author

First thanks a lot for the quick feedback on this @kirsan31!

Is there anything I can do or test to help you to pin-point this issue?

@ab-tools
Copy link
Author

I just tried that again with a completely new .NET 5.0 project - here a minimal example project:
ProjectResourceTest.zip

But you say that you don't see this behavior all the time, @kirsan31?
I tried it a few times with new projects now and I get the same behavior all the time.

Perhaps you could try with the example project above and if you still can't reproduce the issue please let me know how I can help to further investigate this. Thanks!

This is a pretty annoying issue for me to be honest as I have a project were a lot global project image resources are used and now everything is copied kind of 100 times all across the forms. ;-)

@RussKie RussKie added the area-VSDesigner Windows Forms out-of-proc designer related issues label Sep 21, 2020
@merriemcgaw
Copy link
Member

@KlausLoeffelmann , @dreddy-work - what are your thoughts?

@kirsan31
Copy link
Contributor

@ab-tools sorry, I didn't put it exactly. We not use new core designer, we use old .net designer for core project: <TargetFrameworks>net472;netcoreapp3.1</TargetFrameworks>. And in such a configuration some times we see behavior like you described.
But I tested new core designer and pure netcoreapp3.1/net5 project and can confirm this bug with 100% reproducibility. Moreover, the new designer does not understand global resources at all:
Snipaste_2020-09-22_00-06-46
Must be (.net designer):
image

@ab-tools
Copy link
Author

Thanks, @kirsan31, yes, I also noticed that in the meantime: The new designer simply deletes all global image resources from the designer file.

@dreddy-work
Copy link
Member

@KlausLoeffelmann , @dreddy-work - what are your thoughts?

Seems something regressed. Need to check the serialization.

@merriemcgaw
Copy link
Member

Should this be tracked on the designer side @dreddy-work ?

@merriemcgaw merriemcgaw added this to the VS release milestone Sep 24, 2020
@merriemcgaw merriemcgaw added the 💥 regression-preview Regression from a preview release label Sep 24, 2020
@kirsan31
Copy link
Contributor

Just checked on 16.8.0 P5 - same behavior (not working).

@dreddy-work
Copy link
Member

I am looking into it currently. Will update this thread soon.

@9ParsonsB
Copy link

This is still happening on 16.8.0.

Also, the net5 designer does not show images for buttons created in netfx, however when running the program the images show as expected

@gitskotjuko
Copy link

May I ask if there any progress with this issue? It's the showstopper in our migration.

@dreddy-work
Copy link
Member

dreddy-work commented Dec 3, 2020

This is a design time issue and work is currently in progress. Basic scenarios implemented and work in progress for some build/rebuild scenarios. Expect it to be available in VS 16.9 preview 3.

@ab-tools
Copy link
Author

ab-tools commented Dec 3, 2020

Good to hear that this is currently in progress - thanks for the update on this @dreddy-work!

@jeremy-waguet
Copy link

I cannot finish the migration to .NET 5 for my projects because of this issue. I am heavily relying to global resources to avoid local resource duplication

@ab-tools
Copy link
Author

Yeah, I'm also very interested in this.

The release of VS 16.9 preview 2 was on the 8th of December, so let's hope that preview 3 is not too far away anymore. ;-)

@kirsan31
Copy link
Contributor

@jeremy-waguet

I cannot finish the migration to .NET 5 for my projects because of this issue. I am heavily relying to global resources to avoid local resource duplication

Hmm, I'm wondering how you transition to a new designer when we don't have any information about supporting user controls in it?

@jeremy-waguet
Copy link

@kirsan31 Running VS 19 v16.8.4 stable, I have no issue with the new designer other than this one. All I did is reverting to the .NET FX default font (instead of the new default font for .NET 5) by manually inserting this line in my forms.Designer.cs in the InitializeComponent method :

this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);

After that, all the controls, including user controls and external referenced controls do look exactly the same as with the .NET FX version (pixel perfect !) except with some controls like DataGridView or ToolStrip that have some minor changes (color enhancement, different padding).

For now, and because of this issue, I still have to rely on the .NET FX version of my projects for releasing.

@AraHaan
Copy link
Member

AraHaan commented Jan 17, 2021

I always had the problem even with .NET Framework, however yes I do agree it does get annoying when you actually have all of the resources in a project level resx file instead of the form's own resx file.

It would also be nice if localization of forms could be loaded from the project level resx file as well too but RIP might cause conflicts with other forms in a project then.

Although my project is stable on .NET Core, I do however disable the default Non-Client Area on my forms to provide my own theme-able one, however it seems that when the form is over a certain size the "control" buttons I try to clone in themes I make hard coded in the program for "dark" and "light" mode happen to render at the middle of the custom Non-Client area and idk why.

Also it would be nice if someone could help me actually request the Windows API for the actual glyphs that Windows uses on it's original Non-Client area Caption buttons (minimize, maximize, close, help). Currently I got to try to basically draw my own using only System.Drawing and it sucks.

@RussKie
Copy link
Member

RussKie commented Jan 18, 2021

I'm wondering how you transition to a new designer when we don't have any information about supporting user controls in it?

The team is acutely aware of this gap, and the docs are being worked on.

@kirsan31
Copy link
Contributor

@dreddy-work

This is a design time issue and work is currently in progress. Basic scenarios implemented and work in progress for some build/rebuild scenarios. Expect it to be available in VS 16.9 preview 3.

In VS 16.9 preview 3 this is partially fixed.
net472:
image

net5.0-windows:
image

Also new designer code lack global namespace (I don't know if it's bad):
old:
this.button1.Image = global::WindowsFormsApp5.Properties.Resources.ok_16;
new:
this.button1.Image = WindowsFormsApp5.Properties.Resources.ok_16;

@jeremy-waguet
Copy link

@kirsan31 I'll give a try... Not using 'global' keyword should not be an issue.

@jeremy-waguet
Copy link

With my 'net5.0-windows' project it DOES work! But as @kirsan31 wrote, when editing the image with the designer, the 'local resource' option is checked, instead of the 'project resource file' one. It seems to be a UI issue only since after validating 'select resource' form, the image is not copied to embedded resource anyway.

@weltkante
Copy link
Contributor

weltkante commented Jan 21, 2021

when editing the image with the designer, the 'local resource' option is checked, instead of the 'project resource file' one

Does that mean its no longer possible to have local resources? Both options are useful.

Also new designer code lack global namespace (I don't know if it's bad):

Its not a namespace, it changes name lookup to start at the root namespace instead of in the current scope. Its helpful (and IMHO important) to make generated code compile independently of the namespace shapes, for example consider following scenario:

user code (possibly split across files/assemblies)

namespace SomeNamespace
{
  class SomeControl
  {
    // you will want to place this in the designer
  }
}

namespace UserInterface
{
  namespace SomeNamespace
  {
    // unrelated stuff
  }

  class Form
  {
    // this is being designed, see below
  }
}

designer generated code:

namespace UserInterface
{
  class Form
  {
    // this is being designed, the designer needs to use global::SomeNamespace.SomeControl
    // without global prefix you get the nested namespace which doesn't have the control you are designing
    // the result is that the whole project won't compile with the designer generated code
  }
}

Note that the different namespaces/classes can be in different assemblies. While its not the most common thing to happen, its common enough that I've come across it severeal times in the past.

@kirsan31
Copy link
Contributor

kirsan31 commented Jan 21, 2021

@weltkante

Does that mean its no longer possible to have local resources? Both options are useful.

No, you can use local or global, but you can't determinate (in designer) what (local / global and resource name) currently in use. New designer shows this anyway:
image

Its not a namespace, it changes name lookup to start at the root namespace instead of in the current scope. Its helpful (and IMHO important) to make generated code compile independently of the namespace shapes,

Yea, thanks for clarification, I totally agree. My point is: was this change intentional or not...?

@merriemcgaw
Copy link
Member

We've got the dropping of the Global namespace on our radar. We should be able to get it for 16.9

@dreddy-work
Copy link
Member

dreddy-work commented Jan 27, 2021

There are two issues reported here and both of them being tracked in the designer repo. Here is the work in progress on them

  1. On resource picker dialog, Even though the image that was set last time on the component is a project resource, "LocalResource" radio button is checked on relaunch. Its misleading but no functional issue. We are aware of it and there is a designer specific issue to track the work. This require some investigation on how to bring some of the attribute information into server process. Have not started work on this yet but expect it to be available in VS 16.10 time frame. @kirsan31 and @jeremy-waguet
  2. Droping"global" from the project resource serialization code. This is being looked into. We may be able to get this into 16.9 GA. @weltkante, while i see your code snippet logically proves missing global may break applications functionally, would it be possible for project resources? I mean, project resources code is auto generated by the 'Project System' and I did not figure out any scenario ( where user/developer adding project resource file to project and ending up with nested namespace you mentioned above). Correct me if i am missing anything here.

@weltkante
Copy link
Contributor

weltkante commented Jan 27, 2021

would it be possible for project resources

Its possible for anything that qualifies a class name in a namespace, above was just an example for controls, but there's nothing special about controls. As soon as namespaces exist in multiple places you get this ambiguity. Yes this also happens with resources, they are placed implicitly in a namespace and similar conflicts can happen.

I mean, project resources code is auto generated by the 'Project System' and I did not figure out any scenario ( where user/developer adding project resource file to project and ending up with nested namespace you mentioned above). Correct me if i am missing anything here.

These namespaces required to produce the ambiguity are not generated, when the user has namespaces like laid out above, possibly imported from other assemblies, the whole project will not compile because the generated code is ambigous. The old designer took great care to use the global keyword to make things as unambigous as possible, the new designer is a bit more sloppy here.

I've split my sample code above to be more clear.

Technically you could consult the Roslyn compiler to figure out if a name is ambigous, and only use the global keyword if absolutely necessary. The old designer didn't have Roslyn at its command so it always used the most explicit syntax possible.

@AraHaan
Copy link
Member

AraHaan commented Jan 27, 2021

Not to mention some people (like me) and the framework do not always generate the code to global resources but instead make a file themself named SR.cs.

I think the best bet on this is to basically have a csproj setting for the designer to use something like this:

<AlwaysPlaceResourcesInGlobalResources>true</AlwaysPlaceResourcesInGlobalResources>

(default false)

or:

<DesignerGlobalResourcesOnly>true</DesignerGlobalResourcesOnly>

(default false)

Where if true the designer would always use global resources / place non-localizable resources in the project level global resources file inside of the project itself nomatter what the file name is or the class name of the generated code to it.

@weltkante
Copy link
Contributor

Not to mention some people (like me) and the framework do not always generate the code to global resources but instead make a file themself named SR.cs.

The discussion about the global keyword has nothing to do with "global resources". All project resources are global resources and treated equally I believe? Its been a while, but on Desktop Framework you could have multiple resx files and they were all available from a pool of global resources. The designer would specify the corresponding class/property when generating the source accessing them.

If you think theres a difference between project resources and global resources I'm not aware of it, so please explain.

@AraHaan
Copy link
Member

AraHaan commented Jan 27, 2021

global resources are Resources.resx files or any resx files inside of the Properties folder under the project root.

local resources are the resx files to controls / forms themselves and share the same file names as the control / form.

People easily confuse the 2 all the time.

@weltkante
Copy link
Contributor

weltkante commented Jan 27, 2021

I think we are talking past each other, all resources (as currently supported in WinForms) use resx files

  • local resources are resx files attached to a form or user control and only available within it
  • global resources (or project resources) are standalone resx files which generate corresponding accessor classes

I was under the impression that you differentiated between global and project resources, which is not a distinction that exists, they are the same. Local resources are irrelevant to my argument since they generate a local variable in code and don't need to be qualified by global keyword.

I'm not sure why you think there's a project wide setting needed, and what the point of that setting would be, unless you are asking for new functionality that wasn't present in Desktop Framework

@AraHaan
Copy link
Member

AraHaan commented Jan 27, 2021

Actually global keyword is sometimes needed with those as well because what if multiple projects share the same namespace, I got example of such projects under Elskom/Sdk when under winforms where it would give errors on the compiler on the forms every time I would edit the program that uses those projects under that repository if it was to remove global:: on the specific item inside.

It even can happen if for example one was to do this on their projects too:

// project namespace
internal static class Icon
{
    // load icon images from the resources file within the Properties folder without generating the code to it as this class acts as THE code to it using properties.

}

And then the designer without global:: and the project namespace might confuse it with System.Drawing.Icon.

@dreddy-work
Copy link
Member

"global::" prefix in serializing the designer is fixed and should be available in the upcoming preview release of VS.

Regarding 'Radio button' selection, its lower on our priority list and we have a tracking bug in the private designer repo. As soon as attached PR is merged in the private repo. I will be closing this issue.

@ghost ghost locked as resolved and limited conversation to collaborators Jan 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-VSDesigner Windows Forms out-of-proc designer related issues 💥 regression-preview Regression from a preview release
Projects
None yet
Development

No branches or pull requests

10 participants