How can I extend the .text and .caption property of ALL controls. I want to create a multilanguage App, which load the text from a custom file.
I want to do this:
button1.Text.LoadLocalizedText()
label1.Caption.LoadLocalizedText()
Now, I need the following text result, to get the correct text.
I need "class.button1.Text" as string and for the label "class.label1.Caption" as string.
After I load the custom text, I must set the text dynamically to the "source" property like text or caption.
I hope, someone could help me.
Thanks.
If you want to write a method you can call on all controls, write a extension method for control (see #Adriani6's answer)
public static void LoadLocalizedText(this Control ctrl) {...}
If you want to load a resource localized by your culture, you should use your resource files and create files for each culture.
Create 2 resource files like Resource1.resx and Resource1.de.resx and save your corresponding values to the resource files.
Then, you can load your resources like
[ProjectNamespace.]Resources.Resource1.ResourceManager.GetString("myResource");
or, alternatively with an overload to specify the culture yourself
Resources.Resource1.ResourceManager.GetString("myResource", System.Globalization.CultureInfo.GetCultureInfo("de"));
See Microsoft Docs
If this is WinForms, you can write an extension method for the Control class.
public static class LocalizationExtension
{
public static void LoadLocalizedText(this Control ctrl)
{
ctrl.Text = "My loaded string";
}
}
This way you can target all controls that inherit from Control such as Button and Label.
You just call it using Button.LoadLocalizedText() and Label.LocdLocalizedText() etc..
Related
I want to use localization in my project so I'm using ".resx" files.
I have two files "StringRes.resx" and "StringRes.fr.resx". As you can guess, I want that all the messages of my app change according to the CultureInfo of the user.
But when I do this :
public MainWindow()
{
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr");
InitializeComponent();
}
It doesn't change anything when I do :
Console.WriteLine(StringRes.FirstName);
Indeed, it's always the string in StringRes which is displayed and not the string from StringRes.fr
The both are in the same namespace.
Thank you for any help.
I have created my own test projected an I used "fr-FR" as a culture tag. The test project can be found on my skydrive.
Works perfect.
In short:
I set the culture in the Properties of the project to be en-US as that is what I would want my Resource.resx to be.
Then I created Resource.resx, Resource.fr-FR.resx and Resource.nl-NL.resx.
I filled them with the TestData string. And the created a window with 3 buttons with events hooked to them. Next to the buttons I created a textblock, the textblock is binded to a Text string field.
In the button events I change the culture and the Text field. And you can then see the change happen.
You first need to create your Resource.resx then in the same folder you need to create Resource.fr-FR.resx. The Resource.resx will get a codebehind file, all the cultured resource files should not. If your Resource.fr-FR.resx does have a culture file you did something wrong and it is best to delete that resources file and recreate it so it loses it's codebehind.
I have created simple controls that are based on dot net controls . For example there is a simple GridView control that is based on dot net GridView control , I just set some setting in my control to use it in my .aspx pages , for example I set the Width of GridView in the constructor method :
// constructor of my custom class
public GridView(): base()
{
this.Width = new Unit(100, UnitType.Percentage);
}
and also I've added some custom properties :
public int SelectedID
{
get
{
if (ViewState["SelectedID" + this.ID] == null)
ViewState["SelectedID" + this.ID] = "-1";
return Convert.ToInt32(ViewState["SelectedID" + this.ID]);
}
set
{
ViewState["SelectedID" + this.ID] = value;
}
}
The *Problem* : when I use Tools>Generate Local Resource in VS2010
the aspx markup before I use this tool is like this :
<RPC:GridView ID="grdData" runat="server" onrowcommand="grdData_RowCommand">
but this tool adds any public property or any setting to my aspx markup , like this :
<RPC:GridView ID="grdData" runat="server" onrowcommand="grdData_RowCommand"
meta:resourcekey="grdDataResource1" SelectedID="-1" Width="100%">
I don't like VS2010 add my settings (like width) and my custom properties (like SelectedID) to aspx markup , this prevent me having the ability of changing my custom control code and reflect changes in all aspx pages that include this control , for example if
I change the width of my control to 50% , it doesn't reflect to any pages
Please tell me what should I do to fix my problem
Thank you very much for your feedbacks
This is a slightly complicated topic to address in one answer here to be honest! There are more than one approaches you can take to resolve this problem. It all depends on the kind of properties your control has and if it is a templated control or not. As a quick fix try decorating your public properties with the following attribute
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
or if you don't want the user to be able to set the public property at all via HTML markup then use
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
another attribute declaration which will be helpful with
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
is
PersistenceMode(PersistenceMode.Attribute)
I've found doing any initialisation in the ctor causes major headaches for local resource generation (even corruption). Use the DefaultValue attribute on properties and/or use OnLoad if possible. (As a side note use CSS rather than explicitly setting control width).
Im working with Sitefinity and I'm developing a Control Designer - however i dont think my question is specific to SiteFinity.
I have a class such as:
public class CaseStudyFeaturedItem : CaseStudySelectorControlDEsignerBase
The class it is inherriting from is itself inheriting from UserControl, like so:
public class CaseStudySelectorControlDesignerBase : System.Web.UI.UserControl {
Within CaseStudyFeaturedItem is it possible to load a template which is an embedded resource and then access the controls on that control?
So essentially, I have usercontrol.ascx which is an embedded resource so has a string like:
mynamespace.myclass.usercontrol.ascx;
And from within CaseStudyFeaturedItem I want to be able to load that usercontrol and then modify the controls (i.e. literals/labels) that are within it?
Is this possible?
Thanks
Al
We do this with every control in Sitefinity, but it would be a little complicated to do with your own custom controls (I assume you are using Sitefinity 3.7). The steps are the following:
- Implement a template container control, inheriting from GenericContainer:
protected class ItemListContainer : GenericContainer
{
public virtual Repeater RepeaterControl
{
get { return base.GetControl<Repeater>("repeater", true); }
}
}
- You need to get the template from the resource (use ControlUtils.GetTemplate method - Sitefinity does that for you):
public virtual ITemplate ItemListTemplate
{
get
{
if (itemListTemplate == null)
itemListTemplate = ControlUtils.GetTemplate(<virtual path to template>, <resource file name>,
<type to determine assembly for template>);
return itemListTemplate;
}
set
{
itemListTemplate = value;
}
}
- You need to call InstantiateIn method of the template, and pass it the container control
listContainer = new ItemListContainer();
ItemListTemplate.InstantiateIn(listContainer);
- Access all controls through the container
listContainer.RepeaterControl.DataBind();
In Sitefinity 4.0 we've included a base class for all controls, which will give you this functionality out of the box. In 3.7 though, you'll have to do all this by hand.
The ControlUtils class is in the Telerik.Framework.Web namespace. The code above is how this all is done in the ContentView control, you should probably make slight modifications depending on your case.
Cheers,
Slavo
The Sitefinity team # Telerik
Yes it is possible, but I'm not entirely sure what you're trying to accomplish based on your question. You can use LoadControl to dynamically load user controls. If you cast the result to the appropriate control type, you will then have access to all of its properties. From there, you can add it into whatever container you want to hold it. Is that the kind of thing you're trying to do?
If I put a control in a .aspx file like this;
<asp:TextBox ID="protectedTextBox" runat="server">Some info</asp:TextBox>
I get a declared control in the page's .aspx.designer.cs file;
protected global::System.Web.UI.WebControls.TextBox protectedTextBox;
But I'd like to change the access modifier of the control to public. Is there any attribute or similar that I can set to change the access modifier?
Here's why I want to do it. I am trying to have cross-page postbacks work nice and neatly. I have two pages:
FirstPage.aspx
MyTextBox : textbox
MyButton : button, #PostbackUrl=Secondpage
SecondPage.aspx
MyLabel : label
When the user clicks FirstPage.MyButton, I want to write the value of FirstPage.MyTextBox.Text into SecondPage.MyLabel.Text. I could do it with Page.FindControl, but this seems like a poor substitute to casting the previous page as a FirstPage object and referring directly to the MyTextBox control on it. Something like this;
// on the page_load of SecondPage.aspx;
var previousPage = this.PreviousPage as FirstPage;
this.MyLabel.Text = previousPage.MyTextBox.Text;
Is there any way to change the access modifier?
You can just delete the declaration from the designer and put it in your code behind.
The comments around the declaration say to do this.
/// To modify move field declaration from designer file to code-behind file.
One option I've considered is writing a public property which exposes the original page;
public TextBox PublicTextBox { get { return this.MyTextBox; } }
Which would get the job done, but seems hacky.
Steve, exposing that page's controls would make sense if you'd need to manipulate those controls, but in your case you just need to pass some data (that string) to the other handler, so I would expose that and not the control itself.
We have a RichTextBox WPF control and since we control the layout, we simply cannot allow any rich content...
Therefor, we need to strip all data except text from the clipboard. For example, if someone is trying to copy/paste lets say text from a table directly from Microsoft Word, the RichTextBox also takes into account that this text was 1. originally from a table, 2. bold and 3. underlined, and create all sorts of inline content to accomodate all these properties of the text...
This is not appropiate behaviour in our case, because it can break our inline layouts.. we just want the clean text...
The most simple approach would be, in the preview paste command:
Clipboard.SetText(Clipboard.GetText());
and be done with it... But you guessed it.. Clipboard operations are not allowed in partial trust...
We also tried a dirty nasty hack, using a hidden Textbox suggested by this link:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/5b5bcd71-2eea-4762-bf65-84176c919fce/
Like so:
public static class ClipboardManager
{
private static readonly TextBox textBox = new TextBox {AcceptsReturn = true, AcceptsTab = true};
public static void SetText(string text)
{
textBox.Text = text;
textBox.SelectAll();
textBox.Copy();
}
public static string GetText()
{
textBox.Clear();
textBox.Paste();
return textBox.Text;
}
}
And then call it like this:
ClipboardManager.SetText(ClipboardManager.GetText());
This works well in full trust, but for some reason, both Copy and Paste methods of TextBox do not work in partial trust...
Does anyone know how to retrieve the Clipboard's content in WPF/partial trust ?
Thanks
Edit: As Nir pointed out.. I know it's not very nice to mutate data from your clipboard.. But my question will be answered just the same if someone can just point me out how to retrieve only the text from the clipboard in partial trust :)..
It's simply not possible.
In the end we used a toggle button where you could toggle to a textbox, paste it in there, and toggle back to our control. Nasty, but it works.
http://msdn.microsoft.com/en-us/library/aa970910.aspx says only "Plaintext and Ink Clipboard Support" in Partial Trust. Full Trust is required for "Rich Text Format Clipboard"