How to reference/use Resource between multiple projects inside solution - c#

I create a solution with 3 projects
ClassLibrary1(WPF Custom Control Library)
MyButton.xaml
MyColor.xaml
ClassLibrary2(WPF App, Output type : Class Library)
MyWindow.xaml
WpfApplication(WPF App, Output type : Windows Application)
MainWindow.xaml
MainWindow starts MyWindow, and MyWindow create a Button which uses the color(mygreen) in MyColor.xaml
And VS reports : The resource "mygreen" could not be resolved.
But in MainWindow, it works ok.
How should I reference resource in ClassLibrary2 from ClassLibrary1??
I hope I described my question correctly.
New Question:
If the WpfApplication change into a WinForm Application. My answer doesn't work anymore.

I find the answer:
1.right click on ClassLibrary2
2.select the item as follows:
enter image description here
3.select the MyColor.xaml the click the "Add As Link":
enter image description here
4.Add the MyColor.xaml in App.xaml
5.If I use StaticResource mygreen. The vs reports error still, but complies and runs well.
If I use DynamicResource mygreen, the error is gone and everything goes well.
Question:
I have no idea about how to add the folder(including MyButton.xaml and MyColor.xaml) as a link.
This answer works in my demo solution, but not in the solution I'm working on. I'm looking into why

You should add reference the projects you want to use into the entry point project.
Or create a nuget package out dll if you're creating something is to compete with mahapps metro.
To avoid circular references you need to think about what references what and what your theme these brushes form is exactly.
In my simple experiment, my wpf exe references both a usercontrol library which has a brush in it and a custom control library with the control which did not reference that brush.
The exe references both projects, uses the brush and of course it all works fine.
Custom controls are intended to allow for theming. Where you have (say) dark brushes for dark theme and light for light.
The themes can each provide templates and their brushes might be hard coded but are at least within the theme project OR you can have one template which references abstracted brushes.
Where you are essentially just switching out brushes for theming you would have default values within a resource dictionary in the theme project.
Instead of referencing both dll from the entry point you could potentially reference a brushes dll from both the custom library and the entry point.
If you're not using those brushes in the custom library that's a bit pointless.

Related

Why is XAML(WPF) not searching in my XML namespace definitions for the controls?

I've two similar projects. One is a Silverlight project and the other one a WPF. Both of them containing some namespaces and plenty of custom user controls.
As the controls are distributed over many namespaces, I have to define quite a few namespaces, when I'm using them. So I started to define the XML namespaces in the AssemblyInfo.cs:
[assembly: XmlnsPrefix("http://ui.example.com/xaml/touch", "cui")]
[assembly: XmlnsDefinition("http://ui.example.com/xaml/touch", "example_ui.controls")]
[assembly: XmlnsDefinition("http://ui.example.com/xaml/touch", "example_ui.themes")]
Now I have to define only one namespace in each file:
xmlns:cui="http://ui.example.com/xaml/touch"
Unfortunately this only works in Silverlight. My question is, how do I get this to work in a WPF project?
In the WPF project I get errors like this:
Error 5 The tag 'LookUpField' does not exist in XML namespace
'http://ui.example.com/xaml/touch'. Line 7 Position 14. D:\src\prototype\lookup-control\lookup-control\MainWindow.xaml 7 14 lookup-control
Althougth the tutorial worked for Silverlight, I believe it may be inaccurate for WPF. See accepted answer here.
I have a separate assembly with custom controls in WPF and I'm able to use the XmlnsDefinition attribute without a problem. I think the problem lies within the definitions need to exist before the assembly is built. So even though controls will show up in your designer, it can't be built because the compiler needs the definitions while compiling the XAML in BAML which are built into the assembly at a later point.
Edit
I created another WPF user control library and added the same XmlnsDefinitions you used, added the reference of the user control library to my WPF application project, used <cui:UserControl1 /> in my MainWindow.xaml and had no errors.

What type of project should I create if I want them to act as individual modules in Prism WPF?

I'm having some issues using an App.config file to load modules as outlined in another question I started and was thinking through what the issue might be. I'm using Mike Taulty's Prism tutorial, in which you create individual projects within the solution to act as containers for the modules.
Some of the projects are created as a Class Library, while others should be console applications. I have my main project (with the Shell, Bootstrapper, etc) as a Console Application, but I ran into an error stating "[the project] does not contain a static 'Main' method suitable for an entry point" when setting the sub projects as Console Applications.
My solution? Set them up as Class Libraries instead since it gets rid of the error! I think it's possible that the modules aren't loading because they're Class Libraries, but I have no idea since I'm so new to all of this. Any insight would be much appreciated!
Modules should be class libraries. Only the shell needs to be an executable as this is the entry point of the application. The shell executes, starts the bootstrapper which discovers the modules based on how you configure the module catalogs.
As an extension to this, if a module project is declaring a lot of WPF views and custom controls it may make sense to declare the project as a WPF Custom Control library to get the project set up nicely out of the box rather that just a plain old class library. But either way never a module is never an executable such as a WPF or Console application.

Create a component for the palette

I have never created a component before, but now have a few which are basically .cs files. They are of type System.Windows.Forms.Control.
But they are only available on the control palette when I am using the solution they are part of. It makes use of a few images which are in the /Resources folder.
Is there a way to make the component into a DLL, so that I can use it in any project by simply referencing it? Or else, make it into a component that always appears in my palette?
You need to create a Control Library project, which is a Class Library (DLL) that contains public classes that inherit Control.
You can then add a reference to the compiled DLL (or to the project if it's in the same solution) and the controls will appear in your toolbox.

Read resources from a DLL file

I've two Visual Basic 2008 projects - one is a class library project and another is a Windows Forms project. In the class library project, I've defined some strings in the project resources (project properties > Resources tab).
I build that class library project and get the DLL file from the debug folder and added up as a reference in my Windows Forms project.
How do I read those strings from the referenced DLL file?
While you can dynamically load the DLL as ho suggests, it's fine to use a reference as you have done. In fact I would recommend using a reference unless you had a particular requirement to dynamically load the resource assembly.
As to accessing the resources there are a few things you need to do.
In the resource assembly you will need to ensure the resources are public. By default resources are set to internal which means you will not see the resources in the winforms app. Double click on Properties\Resources.resx to open the resources view. In the top toolbar you will see a label "Access Modifier" next to a combo box drop down. Change the selection to public.
You will need to reference the assembly from the forms app. You have stated you have already done this. Just a note that a better way to do this is to create a solution that contains both projects. Then in the forms app choose add reference. Click on the Projects tab up the top. Double click on the resource DLL project name. This works better than referencing the debug DLL directly since it means if you change between a release build and debug build in your forms app, it will automatically build a matching release/debug version of your resource assembly.
Once you have added the reference you can simply reference the type out of the resources DLL, e.g.
ResourceDLLNamespace.Properties.Resource.ResourceName
Just a note, you need to be aware of type name clashes if you are using the same namespace for your forms app and resource DLL. In this situation both your forms app will have access to it's own Properties.Resources class as well as that of the resource DLL. You can do two things to avoid this:
Use a different namespace between the two assemblies
In the resource assembly don't include a default Properties\Resources.resx resource dictionary. Delete it and manually add a new resource, i.e. Add New Item and select "Resources File". You should find that you will not be able to add the new resource dictionary to the Properties folder - add it to the root or some other folder as you require. This will automatically give it a different type name by virtue of being in a different folder. You still may want to avoid using the resource file name of "Resources" however, as if you have all the relevant namespaces in scope via using statements you will get the same issue that the compiler won't know which version of Resources to use.
-Donovan
I think you just use System.Reflection.Assembly.Load to load the other assembly then use the constructor of System.Resources.ResourceManager that takes an assembly.
Note, I don't think it needs to a reference for this to work.

Different location of assemblies stopped the type casting

I am writing a custom Control class in C# for my main project.
There're 2 projects, one for my Control and one for my main project. These 2 projects are in the same solution. I add a reference from my main project to my Control project. I notice that the first time after I drag my Control from the Tool Panel onto my main winform, an assembly folder was generated at the C:\Users\XXX\AppData\Local\Microsoft\VisualStudio\9.0\ProjectAssemblies, and the folder name is something like "jlebh-py01".
The first build is always OK, but after I rebuild my Control class or whole solution, a new assembly folder will be generated at C:\Users\XXX\AppData\Local\Microsoft\VisualStudio\9.0\ProjectAssemblies, and then problem arises, my Control fails to behave well because Visual Studio says that the two types "originates from different location". The error message is as below:
[A]MyControl.TypeXXX cannot be cast to
[B]MyControl.TypeXXX. Type A orginates
from assemblyXXX at location
'C:\Users\XXX\AppData\Local\Microsoft\VisualStudio\9.0\ProjectAssemblies\jlebh-py01\MyControl.dll'
Type B originats from assemblyXXX at
location
'C:\Users\XXX\AppData\Local\Microsoft\VisualStudio\9.0\ProjectAssemblies\ue4i-z3j01\MyControl.dll'
If I reference the Control DLL directly instead of through project reference, or never rebuild the Control project after use my Control in the main project, things seem to be OK.
Does anyone knows why? Is it the proper way to develop a control and a main project within the same solution?
From what you explained - it seems that the main project in your solution is not updating the reference to the control library that you have. I have been working in ASP.NET for a couple of years at least, and have had similar problems with referenced assemblies, but there was always a very simple fix to it - Rebuild the main project. This should clean it, and then run a fresh build.
Another thing you can try is add a variable assembly version to your control. In the project properties, assembly information, try set the version number to 1.0.* This will force the last two version numbers be based on the day and the time of the day, and each time you rebuild the control- it will have a different version. As long as the main project keeps the version updated - which it should - there shouldn't be any problems..

Categories

Resources