Help with c# input dialog

Frank

Certified not a majority
Veteran
I have this really (REALLY) stupid problem: how do I make an input dialog in c# .NET? Just a small form, with a textbox and an "ok"-button.

The obvious way is to do it like this:

InputDialog MyInputDialog = new InputDialog();
MyInputDialog.ShowDialog();
string s = MyInputDialog.MyInput.Text;

While that works in .NET when running on Windows, (I think) that is because Windows has a lax garbage collector. When run on a Pocket PC (Windows .NET Compact Framework), I get a NullReferenceException, as I should.

Edit: (Type)this.Parent or (Type)this.Owner both give a NullReferenceException as well.

And the modal result is a set: { "Yes", "No", "Cancel" } etc. You cannot have a form return any other value.


So, how do I do it? The only solutions I can think of are:

- Use event handlers (make a new handler class, and have the parent add a message handler to the client form)

- Start the input dialog as a new thread and use the tread synchronization mechanism

- Remove all the logic from the forms and start them all from a global unit

- Use a temp file or a static class to hold the value


But there has to be a simple solution, right? An existing class that already does this. Or another solution that allows me to write a library class that simply returns me a value from anywhere?
 
Last edited by a moderator:
I have this really (REALLY) stupid problem: how do I make an input dialog in c# .NET? Just a small form, with a textbox and an "ok"-button.

The obvious way is to do it like this:

InputDialog MyInputDialog = new InputDialog();
MyInputDialog.ShowDialog();
string s = MyInputDialog.MyInput.Text;

While that works in .NET when running on Windows, (I think) that is because Windows has a lax garbage collector. When run on a Pocket PC (Windows .NET Compact Framework), I get a NullReferenceException, as I should.

Edit: (Type)this.Parent or (Type)this.Owner both give a NullReferenceException as well.

And the modal result is a set: { "Yes", "No", "Cancel" } etc. You cannot have a form return any other value.


So, how do I do it? The only solutions I can think of are:

- Use event handlers (make a new handler class, and have the parent add a message handler to the client form)

- Start the input dialog as a new thread and use the tread synchronization mechanism

- Remove all the logic from the forms and start them all from a global unit

- Use a temp file or a static class to hold the value


But there has to be a simple solution, right? An existing class that already does this. Or another solution that allows me to write a library class that simply returns me a value from anywhere?
I can only guess here, but I think your myInput has been disposed. Try to store the myInput.Text into string property of myInputDialog before closing the dialog.
Something like this:

protected override void OnClosing( CancelEventArgs e )
{
base.OnClosing( e );
InputString = MyInput.Text;
}

If that does not work use a delegate or event handler.
 
I can only guess here, but I think your myInput has been disposed. Try to store the myInput.Text into string property of myInputDialog before closing the dialog.
Something like this:

protected override void OnClosing( CancelEventArgs e )
{
base.OnClosing( e );
InputString = MyInput.Text;
}

If that does not work use a delegate or event handler.
As it's a modal dialog, if I hide or inactivate it, the whole Pocket PC freezes, which makes sense. There isn't much in the way of states or events for forms, there isn't even an OnShow event. That means: I have to close the form, and it is disposed immediately. As I get another NullReferenceException when I try to show it again.

So, the moment the calling function resumes, the whole object is gone. Including variables.

Delegates might work, but should use events AFAIK. I'm working on that now, but I really would want something a lot simpler.
 
- Remove all the logic from the forms and start them all from a global unit

This is the option I use these days, but I don't work on Pocket PCs.

What I sometimes do is create a property on my form or control that can pass a reference to a variable by the owner object (form or class).

E.g.: myInputDialogue.ValueObject = sString

And then on the frmInputDialgue I update the ValueObject (if set, i.e. not Nothing) in the frmInputDialogue.Text_Changed event.

I don't know if you can work that way on the PocketPC?
 
So, the moment the calling function resumes, the whole object is gone. Including variables.
Can't be since your still holding a reference to MyDialog. So maybe MyInput and MyDialog are disposed and the MyInput.Text property no longer accessible, but the MyDialog object is still there.
 
- Remove all the logic from the forms and start them all from a global unit

This is the option I use these days, but I don't work on Pocket PCs.
Yes, I did that as well on my last project, which also was a bit bigger and ran multiple differend forms and threads on different monitors. But it's a lot more work, and you have to make everything in the global unit static.

What I sometimes do is create a property on my form or control that can pass a reference to a variable by the owner object (form or class).

E.g.: myInputDialogue.ValueObject = sString

And then on the frmInputDialgue I update the ValueObject (if set, i.e. not Nothing) in the frmInputDialogue.Text_Changed event.

I don't know if you can work that way on the PocketPC?
Yes, but that only works by using delegates to add event handlers to the main and child forms between the create and the show. Which means a lot of custom code for each form that needs to hand values back to the parent.
 
Can't be since your still holding a reference to MyDialog. So maybe MyInput and MyDialog are disposed and the MyInput.Text property no longer accessible, but the MyDialog object is still there.
I think the garbage collector on .NET CE is very agressive, as those PDAs have very limited resources. And I'm pretty sure Close() simply calls Dispose(), bypassing the garbage collector altogether.
 
I think the garbage collector on .NET CE is very agressive, as those PDAs have very limited resources. And I'm pretty sure Close() simply calls Dispose(), bypassing the garbage collector altogether.
Ok, I have now recreated your scenario using the Device Emulator. I can close the form and still access the textbox. My guess is your bug lays somewhere else. Maybe you could post the code, I would gladly take a look at it.
 
I just re-checked it myself, and it does indeed work...

I did it like that initially, and I thought I had tested it, but it ceased to work. While debugging, it didn't work at all like that, and now it again does work.

Thanks!
 
Back
Top