Click here to Skip to main content
15,886,518 members
Articles / Desktop Programming / Windows Forms

Content-driven Input Dialog

Rate me:
Please Sign up or sign in to vote.
4.89/5 (9 votes)
20 Nov 2015CPOL3 min read 16.4K   444   14   5
Self configuring input dialog box for quick data collection in a Windows Forms solution.

Introduction

Have you ever needed to collect simple information in an application that needs more than MessageBox? Developers can spend hours coding different forms for each data instance. This solution, InputDialog, will take a single, simple data type, or a more complex class, and display a form that can collect the information for the user and return an updated data object.

Each data type's input is restricted to valid values.

You can use both simple and more complex data types, as show by these samples:

    

Using the code

Simple Method Call

To just get a string (like in the small sample above) code:

C#
string s = "";
if (InputDialog.Show("What is your name?", "", ref s) == DialogResult.OK)
{
   // Do something with the 's' variable
}

Collecting more items can be done by passing in a class or structure. For example to get the larger sample above:

C#
public class A
{
   public enum AGender { Female, Male };
   
   public string Name { get; set; }
   public int Age { get; set; } = 25;
   public bool Married { get; set; }
   public AGender Gender { get; set; }
}

public void CollectA()
{
   A a = new A();
   InputDialog.Show("Please provide some basic information:", "Personal Info", ref a,
      SystemIcons.Information.ToBitmap());
}

Component

If you're more of a visual coder, you can add this InputDialog.cs file into your project and then you should see an InputDialog item in your toolbox.

Adding this component to your form will place an item in the component tray:

You can then look over at the Properties panel and make changes there:

Calling this from your form would then be as simple as:

C#
int data = 100;
inputDialog1.Data = data;
if (inputDialog1.ShowDialog(this) == DialogResult.OK)
   data = (int)inputDialog1.Data;

And you get:

Control display using Attributes

If using a class or structure, you can even control the label and display order using the InputDialogItem attribute:

C#
public class A
{
   public enum AGender { Female, Male };
   
   [InputDialogItem(Hidden = true)]
   public bool unshownSetting = true;

   [InputDialogItem("Full name", Order = 0)]
   public string Name { get; set; }
   [InputDialogItem(Order = 1)]
   public int Age { get; set; } = 25;
   public bool Married { get; set; }
   [InputDialogItem(Order = 2)]
   public AGender Gender { get; set; }
}

All public fields and properties will be shown until they have the InputDialogItem.Hidden property set to 'true'.

The order is somewhat arbitrary as reflection is used to gather those values. To specify the order, set the InputDialogItem.Order property. Any ordered items will proceed unordered items.

By default, the label for each item is the name of the field or property. To change it, use the first parameter of the InputDialogItem attribute and set it to the value you desire (like the Name property above).

The class above will produce this dialog:

Support for multiple types

All of the following types are supported as members of a class or structure or as stand-alone objects:

Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, Single, Enum, Decimal, DateTime, String, TimeSpan and Guid

Each will show an error if the user tries to add an invalid string and each prevents typing unsupported characters.

Lessons Learned

Using Reflection

To accomplish this input dialog, I'm of course using reflection. I determine the type of the object passed in and then use the various methods and properties of the Type class to decide how to build out the UI.

Since many of the types are actually structures or primitive types, I needed to pass in the value as a reference so I can change its value upon a successful return.

The nasty science of TableLayoutPanel

I wish I could say I spent most of my time coding. No. I spent most of my time debugging the strange machinations of the TableLayoutPanel. What did I learn?

  1. The Margin of the control inside the cell is very important. If the Margin is all zeros, then the control is treated differently than if there isn't a control. If the Margin has a value, the entire row or column is affected.
  2. Setting MinimumSize and MaximumSize are oftent the only ways to ensure the size of a cell.
  3. Getting a label to break rows is hard. Internally, it has the right answers for sizing, but fails to apply them.
    1. Set AutoSize = true and Dock = DockStyle.Top
    2. After label is added to the table, set its MinimumSize = Size if its Width < PreferredWidth

Cool event handling shortcuts

Ever need to handle an event but too lazy to build out the handler? Try this:

C#
TextBox tb = new TextBox();
tb.Enter += (s, e) => tb.SelectAll()

This will cause the text in a TextBox to be selected whenever the control is entered.

History

11 Nov 2015 - Initial posting

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
United States United States
I have been a Windows software developer since 1991. Most of what I create fills the need for some aspect of bigger projects that I consult on.

Comments and Discussions

 
QuestionIs there a XAML version around? Pin
GMaier19-Apr-24 22:16
GMaier19-Apr-24 22:16 
Questionthe quick event handler Pin
jrobb22924-Dec-15 13:30
jrobb22924-Dec-15 13:30 
GeneralMy vote of 5 Pin
Luc Pattyn23-Nov-15 3:29
sitebuilderLuc Pattyn23-Nov-15 3:29 
QuestionHaving recently used 'XLForm' on an iOS SWIFT project .... Pin
Garth J Lancaster20-Nov-15 14:28
professionalGarth J Lancaster20-Nov-15 14:28 
Questionhave you consider to post this as a tip? Pin
Nelek20-Nov-15 12:32
protectorNelek20-Nov-15 12:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.