Using external resx files (not embedded) at runtime in C#

1.5k views Asked by At

I have an application where users can define custom elements by adding their own xaml files. These files are loaded by the application on startup. The idea is to be able to extend the application without having to recompile it. These elements will be shown on screen to the user, and the xaml files may contain resource keys which are not included in the resx files of the application itself. So I have a requirement to have separate resx files which the user can edit, that will also be loaded at runtime.

I've looked at the ResourceManager class, and I know that it can be set to access resources from various other assemblies. But from what I gather the resources must be part of an assembly, which is precisely what I don't want. What I want is to have a bunch of files like these:

%ProgramData%\MyApplication\Resources\strings.resx

%ProgramData%\MyApplication\Resources\strings.de-DE.resx

%ProgramData%\MyApplication\Resources\strings.zh-CN.resx

and I want my application to be able to load these files and access the strings in them.

This article https://msdn.microsoft.com/en-us/library/gg418542(v=vs.110).aspx shows two approaches using ResXResourceReader and ResXResourceSet. However, it appears that these classes take a path to a specific file (or a stream), and therefore won't be able to pick the correct file according to current culture and the naming convention. I know I can code this myself, and that's what I'll do if I don't find a better solution. But ideally I'd want something that handles this for me. For instance if it would be possible to point a ResourceManager to a folder instead of an assembly. Is something like this possible?

1

There are 1 answers

0
GatewayToCode On

after a long long searching i found this: If i understand you in the right way you want to create user defined forms in WPF at runtime using xaml. I am not sure but, i think the resource files will not help you out, because all xaml forms precompiled in the assembly. I found something that maybe sounds like a solution for your problem. Its called Sattalite Assembly. In the first step you have to create a new resource file. Second step is to link it with the Assembly Linker (Al.exe). form .net Framework. MSDN Creating Satellite Assemblies

First step create a ResourceFile at Runtime (here a little help)

 public static void CreateResourceFile()
            {
                string resourceFileName = "externeresource";

                    System.Xml.XmlDocument xmldoc = new XmlDocument();
                    XmlTextReader reader = new XmlTextReader("/runtimeWPForm.xml");
                    reader.WhitespaceHandling = WhitespaceHandling.None;
                    xmldoc.Load(reader);

                    ResourceWriter resourceWriter = new ResourceWriter(resourceFileName);
/*Add XmlDocument must be Serializable to store it in     
                    resourceWriter.AddResource("xamlgrid", xmldoc.ToString());   
the Resource, so i stored a String here. (not testet)*/
                    resourceWriter.Close();

                    MessageBox.Show("File " + resourceFileName + " created");
                    reader.Close();

            }

Second step create a Sattlelite Assembly from resource file with Assembly Linker Al.exe

Last step is to load the xaml Forms from the Sattalite Assembly (here a little help)

Uri GridUri = new Uri(/*Note1*/, UriKind.Relative);
Windows.Resources.StreamResourceInfo sri = Application.GetResourceStream(GridUri);
System.Windows.Markup.XamlReader xrdr = new System.Windows.Markup.XamlReader();
Grid grd = (Grid)xrdr.LoadAsync(sri.Stream);
this.Content = grd;

Note1: Resource file - referenced assembly Pack URIs in WPF

Uri uri = new Uri("/ReferencedAssembly;component/ResourceFile.xaml",UriKind.Relative);

Here some usefull Information as i think Construct XAML Forms at Runtime with Resource Files

This is all i found for you and no guarantee for functionallity. Im interested in if this will work for you, so please send an answer on success or if you solved your issue.

PS.: if this works i think you only have to restart you main application to load the new sattalite assembly. Maybe you have to start an ohter application that do the job and after finish automaticly start your main app again.

Best reguards GatewayToCode