Use solution-wide resources with WinForms - c#

I have a Visual Studio 2017 solution, which is split in several C#-WinForm applications.
To have a similar user interface I put all the icons/pictures into one project (ResourceProject) and marked the resource file public.
By directly editing the .Designer-file of a Form I can now explicitly assign the Image to something from the resource file of the ResourceProject by stating
button1.Image = ResourceProject.Properties.Resources.DemoPic
However, from time to time, the designer overwrites this with
button1.Image = ((System.Drawing.Image)resources.GetObject("button1.Image")));
and creates a local resource file, which has the image embedded.
This is exactly what I wanted to avoid in the first place, since I might want to alter easily some icons later on and have those changes directly spread over all projects.
The only way to avoid it seems to be to assign the images not in the Designer file but in some other method in the actual form file.
Is there any other way around this problem?

You should not change designer.cs file, it's auto-generated and any change which you make in the file will be replaced with auto-generated code the next time which you change something in the form.
But to share image resources between multiple projects in a solution with design-time support, you can follow these steps:
Create a class library project, let's call it ResourceLibrary.
Add a Resx resource file to the root folder of the project with this name Resources.Resx.
Open the resource designer and change its Access Modifier to Public. (It will set its Custom Tool to PublicResXFileCodeGenerator)
Add a few images to the resource designer and save it.
Then in the Windows forms project do the following settings:
Add a reference to ResourceLibrary.
Right click on windows forms project and choose Add → Existing item...
Browse to the ResourceLibrary folder and choose Resources.Resx file.
Click on drop-down arrow of the Open button, and choose Add As Link.
Select Resource.Resx which has added to windows forms project and choose properties.
Set its Build Action to None
Set its Custom Tool to a text like None
Set its Custom Tool Namespace to the namespace of the resource in the other assembly: ResourceLibrary.
Rebuild the project.
Then for all the image properties you can choose the other resource file from drop-down in the Select Resource dialog. The code generation will generate correct code for the property and you have a correct build and it works as expected at design-time as well as run-time.
You can clone or download a working example here:
Repository
Download

Related

Deploy .json file with UserControl WinForms

I have built a custom User Control in Visual Studio (Win Forms).
This User Control requires a .json file to be deployed along with it.
Short Version: How is this possible?
Long Version:
When I am testing the User Control from with the Control designer itself, it works no problem.
This would be because I have set the following:
Build Action to Content and;
Copy To Output Directory - Copy if Newer
So when I'm debugging it, everything is there, as I expect it to be.
The problem occurs when I create a separate Win Forms application, and add this newly designed control to the Palette by:
Right click Toolbox->Choose Items->Browse->Browse to the Project Directory of the Control->Select the DLL->OK
It show up on my Palette, but the problem is of course when I drop the User Control onto the form itself. It has no means of getting "MyFile.json" from User Control Application/Dll to the Current Project.
How do I make this work?
Chud
One easy way is to build your json file as a EmbeddedResource instead of Content. That way it will be embedded into the UserControl's binary (the dll file itself). You can then use ResourceManager class to read it in your code.
If you're going to change the content of json file at runtime, you can instead create an application setting of string type that stores the actual json content. This setting can then be read/written easily using ProjectName.Properties.Settings.Default.YourSettingName.
Also note that if you have set your json file's Build Action to Content and Copy to Output Directory to Always Copy, and you add a reference to this project from another project that also exists in that solution, the content file (json file) should get copied to the bin folder correctly. But if your UserControl project does not exist in the current solution, or you're referencing your control through Browse button, you'll not get your content files. This may not seem obvious, but once you think about it, you'll understand that VS cannot figure out what dependencies does a DLL file has if you simply add a file reference.
In the latter case, a setting is the cheapest solution (described above) that you can use.

Visual Studio 2015, can't change access modifier of new resources files

I'm trying to create new resources files in VS2015. I created them fine, but when I try to change the "Access Modifier", the dropdown is disabled...
Any ideas?
I'm working in a ASP.NET MVC 6 (ASP.NET5). The project is a Class Library, but I have tested in Web Project with same results.
Thanks!!
Edit: Added Properties window
Can you check the property of your file and verify if Custom Tool is ResXFileCodeGenerator ? If it's GlobalResourceProxyGenerator, the dropdown will be disabled.
I had the same problem but I found this easy solution Visual Studio's Access Modifier drop down option is disabled for resource file
To summarize:
Right click on your file resource, choose Properties (Alt+Enter)
Change Build Action to Embedded Resource
Change Custom Tool to PublicResXFileCodeGenerator
A) In Asp.net Core projects
This problem is a known bug in Asp.net Core projects and access modifier is on public by default and you can not change it. It will be solved by asp.net core team next updates but if you need internal access modifier you can use my temporary solution:
Add your all items by the resource designer in your Resource.resx and save it
In the solution explorer expand the Resource.resx tree and open Resource.Designer.cs
Replace all public strings in it with internal and save it
Note: every time you save the Resource.resx file you should do the step 3 again.
Finally you should have a Resource.Designer.cs file with access modifiers like this:
Also check the namespace in Resource.Designer.cs file. it should be a appropriate namespace. Sync with your project namespace.
B) In Normal Asp.net projects
If you have not CustomTool property in the Properties panel for your resource (.resx) file to change it to
PublicResXFileCodeGenerator and solve the problem
Then you should change some settings in your project (.csproj) file manually. It's so easy, just follow my instructions:
Right click on your project in solution explorer and select Unload Project
Right click again on it and select Edit .....csproj
In the opened .csproj file, find the .resx string, you will see a block of settings there. That is something like bellow codes.
Change it to something like the following code (include
PublicResXFileCodeGenerator):
.
<EmbeddedResource Include="MyResourceFile.resx">
<SubType>Designer</SubType>
<Generator>PublicResXFileCodeGenerator</Generator> <!--important line-->
<LastGenOutput>MyResourceFile.Designer.cs</LastGenOutput>
</EmbeddedResource>
Save the edited .csproj file
Right click again on your project in the solution explorer and select Reload project
Now open your .resx file and enjoy ;)
Note: use your resource file name instead of MyResourceFile
I've been having a similar problem.
This appears to be a known issue: https://github.com/aspnet/Tooling/issues/339

Windows forms ImageList - Add images with Relative path - No file copy

I'm trying to add images to my tree nodes (ImageList.Add()), but just can't figure out a nice way of doing it.
I've read from MSDN help I should use System.Drawing.Image.FromFile(path). But cannot just get a file somewhere.
I'm building a DLL, and want it to be a single file, no bitmaps being copied together with it.
So I've read I should add Image files to the project and mark them with Build Action as "Resource".
Ok, but where do I get them??? I saw people using it in XAML files, but I don't have that.
Saw people using Resources.SomeName, but can't find those Resources class.
So....How do I do it?? I've got the files marked as resources, just need to add them to the ImageList.
By the way, I'd love to use the path relative to the Code File that is adding the images to the ImageList. But if not possible, just relative to the assembly root.
If you want to use file paths, for items that are in your project, you must set the "Copy to Output Directory" property to "Copy Always" or "Copy if newer", otherwise it won't be in the bin folder, and then you'll be trying to pass a path to a file that doesn't exist. Build action isn't all that important in this scenario.
If you want to use compiled resources, and reference them via the Resources object, see the rest of my answer. I assume you are using Visual Studio, 2005 or later.
To add an image as a compiled resource to a clean Windows Forms project, so that you can access it via Resources.SomeName do the following:
In Solution Explorer, under the windows forms project (mine is called WinFormsApplication1), expand the "Properties" folder. By default this folder should contain: AssemblyInfo.cs, Resources.resx, Settings.settings.
Double-click on the Resources.resx file. This will open an editor for it. You'll probably see a table of strings, with columns "Name", "Value", "Comment".
Click the drop-down arrow on the "Add Resource" button, and select "Existing File", which will allow you to browse to the image you want to add.
You should now see the image appear in a gallery of sorts. Mine has the name TestImage
Now when you edit the code (mine is Fom1.cs), I can access the image as a System.Drawing.Bitmap as Properties.Resources.TestImage.
To my mind, this is the best way to do images that you want compiled into the application. If you want user-added images, you'll need to use OpenFileDialog, or something like that to get your file path. Then the Image.FormFile() will be what you want.

embed xml in custom controls

i create a custom Control and using the XML file now i need to have just one dll file to use that to another project can you help me to embed xml file to my custom control project?
my programming language is c#.net
If you are using Visual Studio (My version is 2008, if you have 2010, this might be slightly different.)
Open properties for your DLL project.
Click the Resources tab.
Click the blue link (if there is one to add resources to your DLL).
Top Left with the little down arrow choose files.
Click Add Resource, find your file and add it. Give it a name like XmlFile with no dots, this is your handle to the file.
Save and Close Properties for the DLL.
Then somewhere in your project you will use this line, or something like it to access your file.
XElement root = XElement.Parse(Properties.Resources.XmlFile);

How to manage icons in solution with several projects?

I have five projects in my solution. Each of them uses some icons (many of these icons are the same in the different projects) and I want to store them in one place.
I tried to use separate project for storing icons, but I got fiasco..
When I use icon from other project (project which contains all icons) Visual Studio automatically copied this icons to the form.resx file.
Explanation:
By the first I can't attach icon (from other project) to my button from designer. Therefore I must to go to the form.designer.cs and manually attach the icon to the button. After these operations VS rebuilt the auto-generated part in form.designer.cs replaced my code with own and copied the icon to the form.resx file.
//my code
this.btnCompile.Image = SharedProject.Properties.Resources.compile;
//code replaced with VS
this.btnCompile.Image = ( (System.Drawing.Image)( resources.GetObject( "compile.Image" ) ) );
You can see that image was copied to local project to the resources. In this case to change button's image is insufficient to replace only my image (compilation.png) in shared project. I need to replace also it in each form where it used.
Question: How to manage icons in solution to avoid duplication and this big inconvenience?
I've solved exactly the same problem but with one limitation. Let's see two possibilities:
1) You want to have ability to update all images by overriding one folder with images in app folder.
You can use Service as #Farzin Zaker suggested. The drawback of that solution is you have to dynamically set up images to controls and in design mode you will not see control with correct images.
2) You want to use Designer.
In that case you have to add those images as resources. The trick is to make VS use relative path to images from the specified folder. By default VS copies all resource files to project Resources folder. But if VS sees that in Resources folder "registered" other file with the same name VS stores in .resx relative path to image. So If you want to add the same image in two project you have to:
- Create folder Resources
- Add image as existing item (as link): in VS you will see the link to image, set action to None
- Add image to project resources section.
You can design a Service project witch will serve Icons or other resources for your other projects. you should just implement an interface like this in your application :
public interface IResourceProvider
{
Image RetrieveIcon(string key);
//you can add other resource types here.
}
then implement this interface in a new class and return related Icon to each key passed to its methods. here you need to browse resx file of this project for requested Icon (Resource)
then in you application you should just call your ResourceProvider class to priovide required resource Items.

Categories