One thing I've always hated about writing software is data entry dialogs. I never found their structure easy to keep track of. Normally, I would check and manipulate the value of each control in the parent form, but this required me to keep track of each and every control's name. As you know, I also like to keep my code as organized as possible. The following block just isn't as organized as I would like it to be:
if (dialog.ShowDialog() == DialogResult.OK) {
myObject.Name = txtName.Text;
myObject.Description = txtDescription.Text;
}
See how I'm relying on the names of controls? That's doesn't seem like a good thing to do, especially when you start to get many controls in one dialog (which you should try to avoid whenever possible, anyway). So, to satisfy my need for organization, I wrote up a little test application which I will now explain.
To hold the data, I created a class called DialogDataCollection that inherits from Dictionary:
public class DialogDataCollection : Dictionary<string, object> { }
Next, to make things easier, I created a class called DataEntryDialog that inherits from Form:
public class DataEntryDialog : Form {
private DialogDataCollection data = new DialogDataCollection();
public DialogDataCollection Data {
get { return data; }
set { data = value; }
}
}
Then, I made my data entry form inherit from DataEntryDialog instead of simply Form. This way, I can don't have to setup my Data property each time. Also remember that you will need to change the code generated by the Form Designer so that it also inherits from DataEntryDialog.
That's really all you need to do. When opening a dialog, just pass some information to it, like so:
SampleDialog dlg = new SampleDialog();
dlg.Data["SomeValue"] = "Hello, world!";
In your dialog's Load event, read the Data collection and populate your controls. When your dialog's Ok button is clicked, simply pass the values of each control back into the Data collection and read them in your parent form:
myObject.Name = (string)dlg.Data["Name"];
myObject.Description = (string)dlg.Data["Description"];
At first, you may say "Well this looks like a lot of work!". The truth is, yes, it is a bit more work. It's not as straightforward as simply referencing a control and grabbing the value of whatever property. However, using this method, you can give your values a more descriptive name, such as Data["Client Name"] and Data["Client Address"] instead of something like txtClientName or txtCLientAddr. Both accomplish essentially the same thing, but the Data collection method is easier to read and understand at a glance.
Aside from descriptive value names, you can also use this to pass multiple objects to a dialog at one time. The DialogDataCollection class is setup to accept any object as a value. Example:
dlg.Data["Client"] = client;
dlg.Data["Projects"] = projects.FindAllByClient(client.Name);
If I wanted to do that before, I would need to setup multiple arguments in the form's constructor and assign them to properties or something similar to that.
Hopefully that helps someone who, like me, hates passing values back and forth between a parent form and a dialog.
Technorati Tags:
winforms,
c-sharp