Access system:string resource dictionary XAML in C# - c#

How do I access the contents in a resource dictionary using C#?
For example, here is my code in XAML:
<system:String x:Key="NewGroup">New Group Name</system:String>
And I want to access it here in C#:
private void OnAddGroup(object sender, ExecutedRoutedEventArgs e)
{
BooksGroupInfo group = new BooksGroupInfo();
group.GroupName = "New Group" + TheTabControl.Items.Count;
TabItem tab = AddGroup(group);
_currentLibrary.addGroup(group);
_currentLibrary.CurrentGroup = group;
}
Instead of typing "New Group" in C#, I would like to replace that and have access in the resource dictionary in XAML. So the command will automatically get the Name that is in the resource dictionary.
I've tried a couple of solutions like:
(System.String)this.FindResource("NewGroup");
Application.Current.Resources[typeof(System.String)];
and so on...
but they do not seem to work.
I am doing a Localization using locbaml and it doesn't parse the Text/Name on C# (or I don't know how to) and that was the only solution I thought was possible.

Usually using FrameworkElement.FindResource like this: string s = this.FindResource("NewGroup") as string; works. It is more likely that the resource with the key "NewGroup" does not exist in the scope of your control or window (whatever this is). You must make sure that the resource is there. E.g. if your resource comes from another file you have to use MergedDictionaries. You can test if the resource is actually acessible try to acess it from XAML that belongs to your codebehind where OnAddGroup is definde.
I hope that makes sense.

Related

Localization with C# Windows Forms, cannot access my .resx File

Hi I created this WinForm Program. It has several Forms.
I looked for a tutorial or someting to help and found this on StackoverFlow.
How to use Localization in C#
It was really helpful but..
I created a ResourceString.de-DE.resx File and added it to the Properties Folder.
Added some Strings so i can test it. And changed the Access Modifier to Public.
Then i wanted to access the Properties Folder to Use the ResourceString.de-De.resx File.
But it doesn't get suggested.
The Code has to look like this in the end :
private void setLanguage()
{
btnSwitchLanguage.Text = Properties.ResourceString.de-DE.btnSwitchLanguage;
}
Am I missing something ?
Any Help is appreciated. :)
Thanks
You don't need to add the Strings.resx file, Your project already has the resource file Resources.resx. Therefore, you should add a new resource file with Resources.de.resx name, if required localization for the "de-DE". So, you can put into this resource file not only strings, but images, icons etc.
There is no need to change the Access Modifier to Public unless you are not going to access this resources from another assembly.
NOTE: When you are working in the Visual Studio the Visual Assist
suggestion will be the same for all languages, starting from
Properties.Resources.
You need to create a default 'ResourceString.resx' file along with al your language specific resx files. Make sure to add the same resources in all resx files. (btnSwitchLanguage, ...).
Well i found my mistake, after reading the Thread again, that i linked in my Post.
There should be a File called Strings.resx (or whatever Name you Choose), which contains the original strings.
And the File which contains another language. (German in my Example).
Should have the same name, except the language comes at the end.
Like this :
Strings.de-DE.resx
After that i just had to change my Code to :
private void btnSwitchLanguage_Click(object sender, EventArgs e)
{
if (Thread.CurrentThread.CurrentUICulture.ToString().Equals("de-DE"))
{
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-GB");
}
else
{
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("de-DE");
setLanguage();
}
}
private void setLanguage()
{
btnSwitchLanguage.Text = Properties.Strings.btnSwitchLanguage;
}

Cannot compile project when declaring a XAML Resource Dictionary in code

I've got a Resource Dictionary called EditorResources.xaml and it contains the following code:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:editors="clr-namespace:MyCompany.Editors">
<DataTemplate x:Key="PasswordEditorDataTemplate">
</DataTemplate>
</ResourceDictionary>
But when I include this line of code in a class:
private EditorResources res = new EditorResources();
It doesn't compile my project. I doesn't display any Errors List view in the .NET IDE but when I look at my Output view, it displays the following error:
error CS0246: The type or namespace name 'EditorResources' could not be found (are you missing a using directive or an assembly reference?)
But, I don't believe the reference is missing as both the resource dictionary and class are in the same project (same level) and I can clearly see the EditorResources type highlighted as Type and IntelliSense kicks in as expected when I hit my '.' key and it displays properties relevant to a Resource Dictionary i.e. .MergeDictionaries, etc...
UPDATE:
if like me, you've stored your resource dictionary (editorresources.xaml) in a sub-folder (Editors), and your assembly is called 'MyCompany.Activity.Shared' for example, don't forget to include the sub-folder in the component's part so that when you call the code provided by #DrewNoakes, you can call the following without any problems:
var res = new ResourceDictionary
{
Source = new Uri("/MyCompany.Activity.Shared;component/editors/editorresources.xaml",
UriKind.RelativeOrAbsolute)
};
Once you have your object, you can access your DataTemplates or other via code.
Seems like you have a EditorResources.xaml file but not a corresponding EditorResources.xaml.cs file.
In this case, the type your XAML file defines is ResourceDictionary. If you wish to have a subclass of that, you need to define the partial backing class and add the relevant attributes in the XAML to link them together.
If you don't need any C# code behind the scenes, just load the ResourceDictionary directly.
Some code like this might help:
var dict = new ResourceDictionary
{
Source = new Uri("/YourAssemblyName;component/EditorResources.xaml",
UriKind.RelativeOrAbsolute)
}

Reading values out of a language.xaml file

I'm creating a C# WPF MVVM application and currently busy with adding different languages.
Right now I use a xaml file which contains a lot of rows like:
<system:String x:Key="btnNew">New</system:String>
<system:String x:Key="btnEdit">Edit</system:String>
The program reads a specific folder, gets the different language files (English.xaml, Dutch.xaml) and adds the selected file to the Resources.MergedDictionaties:
void updateLanguage(int id)
{
string sSelectedLanguage = obcLanguages[id].sRealName; // Get selected language name
ResourceDictionary dict = new ResourceDictionary(); // Create new resource dictionary
string sSelectedLanguageUrl = "pack://siteoforigin:,,,/Languages/" + sSelectedLanguage; // Create url to file
dict.Source = new Uri(sSelectedLanguageUrl, UriKind.RelativeOrAbsolute);
App.Current.MainWindow.Resources.MergedDictionaries.Add(dict); // Add new Language file to resources. This file will be automaticly selected
}
My xaml content with buttons refers with the DynamicResource to the 'bntNew':
<Button x:Name="btnNewSeam" Content="{DynamicResource btnNew}"Style="{StaticResource BtnStyle}" Command="{Binding newSeamTemplateCommand}" />
This works fantastic.
But right now i'm using Observablecollections for comboboxes and I'm adding options in code like this:
obcFunctionsPedalOptions.Add(new clCbbFilltype1("Block", 0));
obcFunctionsPedalOptions.Add(new clCbbFilltype1("Free", 1));
obcFunctionsPedalOptions.Add(new clCbbFilltype1(">0", 2));
But the options "Block", "Free" and ">0" have to be translated with information from the Language.xaml file.
How can I read this specific Xml file with code, get for an example the PedalOptions x:Key and read its options?
Example:
<system:String x:Key="PedalOptions">Block, Free, >0</system:String>
Rather than define the strings in XAML use a resource (.resx) files. You have a default (ResourceFile.resx) file and then language specific ones (ResourceFile.nl.resx for Dutch, ResourceFile.en-US.resx for US English, etc). The system picks the correct resource file based on the current culture settings.
The MSDN has a section on this which you should read.
You can then just have the following in your code:
obcFunctionsPedalOptions.Add(new clCbbFilltype1(Resources.ResourceFile.Block, 0));
You'll need have make this visible to the XAML as follows by defining a class:
public class Localize : INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyChange(String name)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name));
}
#endregion
//Declarations
private static ResourceFile _localizedStrings = new ResourceFile();
public ResourceFile LocalizedStrings
{
get { return _localizedStrings; }
set { NotifyChange("LocalizedStrings"); }
}
}
Then reference this from the XAML:
<local:Localize x:Key="LocalizedStrings"
xmlns:local="clr-namespace:Module" />
You can then use it as follows:
<TextBlock Text="{Binding LocalizedStrings.Block, Source={StaticResource LocalizedStrings}}" />
Thanks for your answer, i did make it work like you told me and the MSDN page:)
So, right now i have one default "LanguageResource.resx" file added to my resources and did test it with a second "LanguageResource.nl.resx" file, and changed the language with CultureInfo("nl").
But, my customer wants a folder where he can put different "LanguageResource.XX.resx" files, the application adds this files from the folder, and he is able to change the language.
My customers doesn't want to compile this program everytime he adds a new language.
So how do i runtime add a few .resx files to the resource manager?

How to use .resx and .resource files in custom server control asp?

I am writing my own server side control and I am using images that are being stored in a .resx file. In the console application this code works fine:
ResXResourceReader rsxr = new ResXResourceReader("Resource1.resx");
foreach (DictionaryEntry d in rsxr)
{
Console.WriteLine(d.Key.ToString() + ":\t" + d.Value.ToString());
}
rsxr.Close();
but here
protected override void RenderContents(HtmlTextWriter output)
{
ResXResourceReader rsxr = new ResXResourceReader("Resource1.resx");
base.RenderContents(output);
foreach (DictionaryEntry d in rsxr)
{
output.Write(d.Key.ToString());
}
}
I get this error:
Could not find file 'C:\Program Files\Common Files\Microsoft Shared\DevServer\10.0\Resource1.resx'
I tried to use the ResourceManager, but it requires a .resource file. I can't access the resgen tool (command prompt does not understand the resgen command) and install it (during the attempt some errors ocured).
My questions are:
Why can't I read .resx?
How to install the resgen tool properly?
thanks.
It is considered good practice to store your resource file under App_GlobalResources folder in application root or in App_LocalResources with the same name as your user control file. So for example user user control is uc.ascx file in local resource folder should be uc.ascx.resx. That way it is easier to maintain and asp.net will automatically detect it.
Now your answers:
First Question:
Use Server.MapPath("~/") points to physical directly where your web.config is. If you want to use a resource file in Controls folder you have to write Server.MapPath("~/Controls/Resource1.resx") to get the path.
Not sure what you want to do with resgen tool? When you compile your application, resource file will also be compiled. select your resource file and click F4, it will show you build action, choose resource in build action and your resource file will be included in assembly.
You can review this post for more information: How to use image resource in asp.net website?
From your description, I understand you need to locate and access the user control's resource file. I found that it works nicely the following way:
Create a App_GlobalResources on project level (via context menu Add -> Add ASP.NET Folder -> App_GlobalResources)
Create the ressource file with the same name as the control, but inside the App_GlobalResources. For example, if the control is named myControl.ascx, then the ressource file's name for the default language has to be myControl.ascx.resx
Create additional ressource files for each language you require. For instance, if you need German ("de-DE"), then add myControl.ascx.de.resx
Add the class MultiLanguageUserControl as follows:
public class MultiLanguageUserControl : System.Web.UI.UserControl
{
public string getResValue(string id)
{
var ctrlPath = TemplateControl.AppRelativeVirtualPath;
var ctrlFile = System.IO.Path.GetFileName(ctrlPath);
var resObj = GetGlobalResourceObject(ctrlFile, id);
if (resObj!=null)
return resObj.ToString();
else
return string.Format("UNRESOLVED[{0}]", id);
}
}
Open the code behind of myControl and make it inherit from MultiLanguageUserControl instead from System.Web.UI.UserControl:
public partial class myControl : MultiLanguageUserControl { //... }
In the HTML code, use the new function, e.g.: <%=getResValue("resid")%>, where "resid" is the name of the ressource string you want to look up. You can also use the HTML-encoding tag <%: instead of <%=, depending on your requirements. Alternatively, you can use getResValue anywhere in your server-sided C# code in your user control to retrieve the value from the ressource file.
Ensure that you support the language detection in the Page_Load event of the page, which uses the user control. How you can do this is described here (look for the function InitializeCulture).
NOTE: If you want to read the page's local resource strings from inside the user control then take a look here.

Silverlight C# - ComponentOne Spellchecker not loading dictionary

This may be a long shot, but I'm using ComponentOne's Spellchecker control for Silverlight. I made a test project, added a plain textbox and a button to it, added the references to the C1.Silverlight and C1.Silverlight.SpellChecker bits, and added the dictionary file to my project.
In the code, I called up the spellchecker on button1's click event and it worked SPLENDIDLY. The spellchecker dialog shows up, and works exactly as it should.
Since that test was successful, I then tried to implement this into my existing project. I've had no success for absolutely NO reason that I can determine, since I used the EXACT SAME code.
Here's the code I use to call the component:
using C1.Silverlight;
using C1.Silverlight.SpellChecker;
using C1.Silverlight.Resources;
public partial class MainPage : UserControl
{
C1SpellChecker spellChecker = new C1SpellChecker();
public MainPage()
{
InitializeComponent();
spellChecker.MainDictionary.LoadAsync("C1Spell_en-US.dct");
}
private void btnSpelling_Click(object sender, RoutedEventArgs e)
{
var dlg = new C1SpellDialog();
spellChecker.CheckControlAsync(txtArticle, false, dlg);
}
The references to C1.Silverlight and C1.Silverlight.Spellchecker are added to this project as well, and the dictionary as been added in the same fashion as well. The issue seems to be that for whatever reason the dictionary is not loading, because the spellChecker.Enabled method returns whether or not the main dictionary has been loaded. If I call MessageBox.Show("SpellChecker Enabled = " + spellChecker.Enabled.ToString()); it shows false, even though the call to load the dictionary is there (as you can see).
What would cause the dictionary to not load? Have I added it to my project incorrectly somehow?
EDIT: I suspect that I have added the dictionary to the project incorrectly, because the ComponentOne reference states:
If C1SpellChecker cannot find the
spelling dictionary, it will not throw
any exceptions. The Enabled property
will be set to false and the component
will not be able to spell-check any
text.
I just don't know what's wrong though because it was added in the same way that it was in the test project (Right clicked on the project.web->Add->Existing Item)
As always, thank you!
-Sootah
You could add the dictionary to the Silverlight app as an embedded resource and then load it using this code:
public MainPage()
{
InitializeComponent();
// load C1SpellChecker dictionary from embedded resource
var asm = this.GetType().Assembly;
foreach (var res in asm.GetManifestResourceNames())
{
if (res.EndsWith(".dct"))
{
using (var s = asm.GetManifestResourceStream(res))
{
sc.MainDictionary.Load(s);
break;
}
}
}
}
I think this post is duplicated in our forum as well, but will answer first here. Please try this:
1) Try to access the .dct file using your browser. If you cannot see it, it's probably because your web server is not serving that type of files. You need ton configure the web server to allow it.
2) verify the URL you are using is correct.http://helpcentral.componentone.com/CS/silverlight_161/f/78/p/86955/241328.aspx#241328
3) Check you are setting everything correctly: http://helpcentral.componentone.com/CS/silverlight_161/f/78/p/81924/227790.aspx#227790
Hope this helps!

Categories