I wrote a window UI by c++ windows form. I'd like to create a string table to localize the Form. My steps are:
1. I set the form localizable=true.
2. Add a new .resx file named (project name).en-US.resx and edit the string table.
3. Set the text of components using the code like
this->button1->Text = resources->GetString("CLOSE");
After I finish setting the text, I build the project and execute it, the button truly show the text. But if I modify the UI(like add component or change the position of the button), the text will disappear after I build again. What's wrong with the code? How can the text always show? Otherwise I need to set again if I modify the form><. Thanks for anybody's help.
Do not make changes to the code that is generated by the designer. Anything inside the InitializeComponent() method. Such changes will disappear when you make another change in the designer and it re-generates the method. Code in the constructor is okay, put it after the InitializeComponent() call.
The better procedure to localize a form is to let the designer generate the .resx file and the code. Change the form's Language property to the desired language, then change the Text property in the property grid. No additional code is required.
Related
I'm working on an old project that supports Windows Forms.
This project contains some ResourceManager for the support of a few localizations. The idea is that you call ResourceManager["SomeResource"] instead of Resource.SomeResource and it returns you a localized string.
And these localized strings are used in the code of the initialization of the form. For example, you have Form1, and in Form1.Design.cs there is some code like this:
Label label1 = new Label();
label1.Text = ResourceManager["SomeResource"];
So the label will be created with an already localized string in the Text.
And we need to add the functionality of changing the UI language without reloading the Form.
We can just set the every Text property of every controls again. But it's a lot of code, the form contains a lot of controls.
We can call the Form.InitializeComponents(), this method will recreate all controls with new localized strings, but in some cases, it works slowly because it reloads some big data again.
Is there some other way to refresh all UI controls and get the new localized strings? Do Windows Forms support some mechanism like Binding in the WPF to create the "connection" between the Text properties and localized resources?
I think that you can achieve this by use of Invalidate() either on the form itself or on a container control that your other controls may be encompassed by.
I change the text property of labels on a windows form. The form displays the correct new labels when displayed in the VS 2010 forms designer. I also change the color of the font.
When I run the program, the window displays the old text values instead of the new text values. The form displays the new font color on the labels.
There seems to be no occurrences of the old text value in the source code. Where is the old text value still hiding?
I clean the solution and rebuild it, but nothing changes.
A colleague observed that this is an artifact of converting projects from VS2005 to vs2008 to VS2010 and suggested a "brute force" corrective measure.
It actually worked.
1) Create a new blank form in the project.
2) In the original form, using the forms designer "Edit" menu, use the "select all" and "copy" actions. This copies all forms objects into the clipboard.
3) Paste the clipboard into the blank form.
4) Copy (most of) the program code from the old form into the new form, excluding anything generated by the forms designer.
5) Delete the old form from the project. Make changes as necessary to use the new form
Not very elegant, but good for meeting a deadline.
Thank you J.H!
Epilog:
"Brian" and "Blogbeard" both had the right direction in suggesting a hidden resource file.
Early in the execution of the code lay a method call to an obscure subsystem that no one knew anything about. That subsystem turned out to be a defunct language translation module which was supposed to translate all of the labels in a form from a native language to a target language.
It was configured to keep the original labels and their translations in a file outside the scope of the IDE. Changes in the form itself were completely ignored if the translator found the label name in its file.
Moving the form contents to another package effectively disabled the translator.
The elegant solution turned out to a three-line change that removed the method call to the translator. (it was no longer required in the application)
I have a winform that needs to be loaded to update its controls' values or properties, before it is to be shown.
I found a stackoverflow question asking the same thing, but it's answer doesn't really help me. Load a form without showing it
Any sample code will be appreciated. Thank you,
Only you need create a new instance of the form and set the values of the controls.
check this code
Var
AForm : ChildForm;
begin
AForm:= new ChildForm;
AForm.textBox1.Text:='Foo'; //this control can be accessed here because the Modifiers property was set to public.
AForm.Show;
end;
Btw remember if you want modify or access the controls of another form you must set the property Modifiers of the control to access to public.
Create the form like this:
form := new MyForm();
Assuming you have implemented a method on MyForm to update the values, call it:
form.Update();//may need to pass parameters here
Show the form in the usual way:
form.ShowDialog();
From MSDN:
Form.Load
Occurs before a form is displayed for the first time.
So you can do all updates to the controls that are necessary before you show the form in this event handler.
But actually it is probably better to use databinding on the controls, so that they automatically reflect the current values you want them to show and you don't have to write any glue code bringing data on controls (and reading from them).
I am working on a WinForm Application.
The Form has many fields/components but is poorly built.
for example a field is used as user name on one case and used as folder path on the other case. Code is quite poorly maintaned.
Is is possible that when i run the application and GUI appears, i can use a tool like 'spy++' which can show me 'names' of the components (not ids). For instance the name of a button or name of a label.
Or if i can use SPY++ for 'names' please tell me?
I would solve the problem by adding a ToolTip control to your form and iterating over each control and adding a Tool Tip message to each control that is the name of the control.
First, add a ToolTip object to your form (from the Tools section of the designer.) You can rename it, but for the sake of my demo, I left it as the default name toolTip1.
Next, add a method similar to the one I'm posting below to the code page of your form. (I'm assuming this is for C# but the code is simple and can easily be modified for VB or C++).
public void AddNameToToolTip(Control c)
{
toolTip1.SetToolTip(c, c.Name);
foreach (Control child in c.Controls) AddNameToToolTip(child);
}
Finally, from within the Form constructor, add the following line of code after the call to InitializeComponent().
AddNameToToolTip(this);
This will add a ToolTip message to each control in your form. All you should have to do is hover your mouse over each control and the ToolTip will pop up a message after a second or two displaying the name of the underlying control.
Alternatively, you can recursively adding a MouseHover event to each control and when the event is fired, write the name of the control to the debugger. This would also work if you are already using a ToolTip control within your form.
I am using WPF and the DocumentViewer to display a document. However, when I use DocumentViewerBase.Print, it gives the "standard" Windows dialog box asking me to choose a printer with the default already selected. How can I get rid of this? I just want to use a Print method that will automatically start printing with no other prompt in between.
I believe in order to do this you would need to write your own printing routine e.g. by overriding OnPrintCommand method of the DocumentViewer. The reason is that default implementation is using PrintQueue.CreateXpsDocumentWriter method to create XpsDocumentWriter object and shows a PrintDialog in order to define its properties. For more details check the DocumentViewerBase.OnPrintCommand with reflector