views:

179

answers:

1

Hi, So, I've got a C# project for Windows Mobile phones and I'm trying to work with the InputPanel. Specifically, I've got one form with a stack of Labels and TextBoxes that collect user input. I have an InputPanel that alerts me when the user opens the SIP. Everything works fine so far. When I get messages that the SIP status has changed, I want to change the height of the Form, which doesn't seem possible.

Here's my event handler for my InputPanel:

void m_InputPanel_EnabledChanged(object sender, EventArgs e)
{
    // :(  this assignment operation doesn't work and it doesn't               
    this.ClientSize = inputPanel1.VisibleDesktop.Size;
    // doesn't work
    this.Size = inputPanel1.VisibleDesktop.Size;
    // assignment operation works, but isn't very useful
    this.visibleHeight = inputPanel1.VisibleDesktop.Height;
    this.InitializeUI();
}

When I say that the assignment operation doesn't work, I mean that the values don't change in the debugger. I can understand that maybe I can't change the size of a Form, but I can't understand why trying to change it wouldn't throw an exception, or give a compiler error.

I have my Form WindowState set to Normal instead of Maximized, but it doesn't make a difference.

Also, I have read http://www.christec.co.nz/blog/archives/42 this page that tells me how I'm supposed to do this, but I can't easily put all of my controls in a Panel because I'm using a bunch of custom stuff to do alpha background controls.

+2  A: 

Changing the height and width of a form in .NET CF has no effect whatsoever, unless its FormBorderStyle is set to None.

However, doing this isn't a good idea in your case, since you don't actually want a borderless form. The proper thing to do in your case is to put all of your controls (labels and textboxes) on a Panel (which is sitting on your form, of course), and then resize the panel as the SIP opens and closes.

Edit: Since I've seen this kind of interface in Windows Mobile, please allow me to give you some unsolicited UI advice. Rule #1 for me with .NET CF applications is: "never use the SIP under any circumstances". The SIP is, of course, completely unusable without a stylus, and not very much use with a stylus, especially with an even slightly out-of-alignment screen.

If you must break Rule #1 (and of course, you have to break this rule for most kinds of free-form text input), then your UI should at least be polite to the user and do two things:

  1. Don't continually resize and rearrange your form in response to the SIP opening and closing. If your form requires the SIP, leave permanent space at the bottom to accomodate it.
  2. Don't make the user open and close the SIP. If your form requires the SIP, open the SIP when your form loads, and close the SIP when your form closes.

Finally, I've generally found it easier to use static methods like this rather than adding an InputControl to each of my forms. I find InputControls to be a pain, and sometimes they get in each other's way if you have more than one form with an InputControl on it open at the same time.

MusiGenesis
The device I'm testing on doesn't have a hardware keyboard, so I don't see how I can avoid breaking Rule #1. I do pop up the SIP whenever a TextBox gets focus, so hopefully I'm not making things too annoying for users. Also, I sort of have to resize the my form because otherwise I'll end up with 50% blank screen most of the time since my app is generally a data viewer that sometimes requires input.Thanks for the answer. Adding a Panel is what I was guessing I'd have to do, but I really didn't want to since it means refactoring a lot of existing code.
thebeekeeper
I can describe one scenario that's sure to annoy users: when they click on a TextBox at the bottom of the screen and the SIP opens, either covering/hiding the TextBox they just clicked on or else pushing all the controls up so that your TextBox remains visible (but no longer in the location your user just clicked).
MusiGenesis
I can see how that might be annoying, but I'm not sure what the alternative is. I can't leave the TextBox under the SIP while the user is typing into it, and my boss definitely won't let me leave half the screen unused during normal operation. Do you know of any examples of applications that have done this really well? I'm new to .NET CF development, so it would help a lot to see what the people who know what they're doing are up to.
thebeekeeper
Sorry, I don't have any links to publicly-viewable CF applications. In my applications, when I need a user to enter a series of values, I usually stick with a "one field per screen" approach, and take the user through a series of screens wizard-style. You can write a generic form for each data type (text, numeric, date, picklist etc.), and then just show these forms to the users in a sequence. One advantage of this approach is that you then don't really need to create any more data entry forms. Instead, you just write a simple method to show the right sequence of data type entry forms.
MusiGenesis
One other advantage of this wizard approach is that your application will no longer look crowded, with all your controls packed together as tightly as possible. With just one piece of data per form, you can show nicely descriptive field names as well as longer descriptions, and use large, easy-to-read and easy-to-thumb fonts and controls.
MusiGenesis
This would probably be too much of a refactoring for your boss to swallow, I'm sure, although there are some hackish ways you could fold the wizard approach into your app using your existing data entry forms (basically, you'd have a method that would create but not show an instance of your original form, then walk through the controls on that form, showing one of your single-item-entry forms for each and inserting its user-entered value into the original control).
MusiGenesis
In your specific case, if it's not easy to add a Panel to your form and then put all your controls on it (if you have code that iterates through your form's `Controls` collection, you have to switch it to the Panel's controls collection, since it's not automatically recursive), you can write a method that your form calls on load, that programmatically adds a Panel, removes all your controls from the form and adds them to the panel, and then wires up the Panel so that it resizes itself to the state of the InputPanel.
MusiGenesis