views:

222

answers:

3

I have to enable all the text in a winforms application to be replaced; it is an old application and is in “maintenance”. The application was written in .NET v1.1 and later bits of it in .NET v2 therefore it does not use any layout controls.

The problem I have is that I need to make the UI cope when a string is longer then the default string. However I don’t wish to make lots of changes to the code due to the risk.

In the past I have found that simple changes like adding a panel to a form and dragging the current controls on to it have lost event hook-up etc. Due to the way the WinForms designer moves the code about, it is very hard to use DIFF to spot this sort of problem. So wish to avoid any changes to the control tree if possible.

So I am looking for some sort of layout manager that I can just add to a form without having to change the rest of the code (or control tree) – any ideals?

Any other options I should be looking at?

(The people that are replacing the strings do not have the skill set to rearrange the controls themselves; it would also be a maintenance nightmare as label may need to have different values for each customer)

(Answers that say, “If I was you I would not start from here are not useful”)


Does anyone know of a layout manager that is external to the control tree? E.g I can point it at a form and it will take over the layout of the controls, without having to make all the controls children of the layout manager.


see also this thread on the msdn Forums.

+1  A: 

I don't have much experience with layout managers, and I'm not really a UI designer, so I am hesitant about replying, but seeing that no-one else seems to be, I chip in with my thoughts.

If your only problem is that you don't trust the designer to do the cut and paste (ie you trust it to do the re-sizing), then you can do that part manually.

What I have done in the past (not because I don't trust the designer, but because I find it is sometimes easier to do it this way,) is :

(Assuming C# and adding a new panel to an existing form)

1) Make sure I have a backup (usually in source control)

2) Add the panel to the form (usually with the designer)

3) Close the designer and open the code (xxx.cs or xxx.designer.cs) and find where it adds all the top level controls to the form and move all of them (apart from the panel) to add them to the panel.

Ie you start with some like (hopefully with more meaningful names)

this.form1.Controls.Add(this.label1);
this.form1.Controls.Add(this.textBox1);
etc.
this.form1.Controls.Add(this.panel1);

and end up with

this.panel1.Controls.Add(this.label1);
this.panel1.Controls.Add(this.textBox1);
etc 

this.form1.Controls.Add(this.panel1);

Newer forms may use the syntax something like this.form1.Controls.AddRange(new System.Windows.Forms.Control[] { this.label1, this.TextBox1, etc this.panel1});

but the principal is the same.

4) Do another backup. (This is where I wished I had a source control package that allowed me to do a temporary/private/personal backup without make it visible to other people.)

5) Open the form in the designer and check that all the controls are there.

6) Start amending the layout as needed.

Alternatively, I haven't tried it, but I would be very surprised if you could not configure Beyond Compare (see http://www.scootersoftware.com) to just compare event hook up lines (ie those containing a += characters) and that should make it a lot easier to spot that if any have been lost.

sgmoore
Thanks, this is very helpful.
Ian Ringrose
+1  A: 

Unfortunately I know of no such layout manager. However, I have a suggestion that includes some minimal (but safe, I think) code changes. I assume below that it is only Labels that you have problems with, but the concept can be expanded to other WinForm objects as well. I also assume that all the text is originally set in the designer.

First, create a class that inherits from Label. Let us call it SuperLabel Do nothing in it for now.

Next, search & replace all instances of

new System.Windows.Forms.Label();

with

new SuperLabel();

This is quite a safe change to do. Of course you should take backups etc as you go along, but your designer and your application should work 100% as before after this replace. After all, for now SuperLabel is just a Label and nothing more.

Finally, hook up to some event like in the pseudo code below:

public class SuperLabel : Label
{
    public SuperLabel()
    {
        this.ParentChanged += new EventHandler(SuperLabel_ParentChanged);
    }

    void SuperLabel_ParentChanged(object sender, EventArgs e)
    {
        // Here you have the Text property, the Size property etc available
        string newText = GetNewTextFromSomeDictionary(Text);
        int lengthOfOriginalText = CalculateLengthOfOriginalText();
        int lengthOfNewText = CalculateLengthOfNewText();
        if (lengthOfNewText > lengthOfOriginalText)
            newText = CreateNewShorterTextSomehow(newText, lengthOfOriginalText);
        Text = newText;
    }

    // TODO: Implement the methods in the pseudo code here ...
}

As you see, this lets you do the code changes very safely and in just one place. In this solution all the new text is added in some key-value dictionary, for example from an xml file or whatnot. This would let the people who replaces the strings do that away from the code, it would avoid making any changes in the designer and it would handle strings that are too long.

Hope this helps!

Halvard
Interesting ideal, hence +1, however I need to create space for the new longer strings, not make them shorter. I don’t think our new Garman uses will be happy with only seeing half of their labels.I am setting the label (and other control) text by reading them from a dictionary in the OnLoad() override in a custom subclass of the Form class. I just walk over the complete control tree, the same thing is done when the user changes the language.
Ian Ringrose
Ah, I see. I misunderstood the problem a bit. Afraid I can't help you then ...
Halvard
A: 

.Net Forms Resize may be of help, it's web site says.

Can be easily implemented to already designed forms with 1 line of code

I have not looked at it in enought details to know, it seems to mostly be about scaling controls when the resolution changes.

Ian Ringrose