Menu

Help-Tutorial-Direct-InputBoxes

Making Things More Interactive

The next feature presented in this tutorial are input boxes. Input boxes are dialog boxes that provide means for entering one or more values. The values can be strings, integers, or any other data type. (You can imagine this a bit like the prompt function from JavaScript, just with support for more than one value and values of various data types.)

Note that most classes related to input boxes are found in their own namespace, so you will have to add the following using directive to the top of your source file:

using TwoLayeredGUI.ValueInput;

In order to display an input box, it is always necessary to create a settings object, in this case InputBoxSettings. The settings object offers various settings for the input box as properties, such as the Title property, which determines the title bar text of the input box:

InputBoxSettings settings = new InputBoxSettings();
settings.Title = "Value Input";

Input fields can be added by adding description objects to the Values list of the input box settings. The value descriptor can be of any subtype of InputValue, so let us use one of the pre-defined subtypes, namely StringValue:

settings.Values.Add(new StringValue());

Lastly, the input box has to be displayed. For Gtk#, we can use the InputBox.Show method for this purpose. The simplest overload expects an input box settings object, as well as an array of System.Object values that must be passed as an out argument. This array will receive the values input by the user, in the order defined in the aforementioned Values list. The Show method returns a boolean value that indicates whether the user confirmed the input by closing the dialog box with the Ok button:

object[] results;
if (InputBox.Show(settings, out results)) {
    MessageBox.Show(string.Format("You wrote \"{0}\".", results[0]));
}

You will notice that the text box in the dialog box was not labeled on its own. That is because we did not specify any label for the input value.

The label is specified as an AccessString, an object that stores a string and some additional information that may be used in different ways depending on the GUI toolkit. We will specify a mnemonic character:

InputBoxSettings settings = new InputBoxSettings();
settings.Title = "Value Input";
settings.Values.Add(new StringValue(new AccessString("Value:", 'v')));
object[] results;
if (InputBox.Show(settings, out results)) {
    MessageBox.Show(string.Format("You wrote \"{0}\".", results[0]));
}

Now, we were talking about other value types and more than one value at a type. As a few pre-defined value types are contained in the libraries of the Two-Layered GUI Toolkit, we will use some of them:

InputBoxSettings settings = new InputBoxSettings();
settings.Title = "Value Input";
settings.Values.Add(new StringValue(new AccessString("Text:", 't')));
settings.Values.Add(new Int32Value(new AccessString("Integer:", 'n')));
settings.Values.Add(new Int32Value(new AccessString("Another integer:", 'a')));
settings.Values.Add(new SingleValue(new AccessString("Floating point number:", 'f')));
object[] results;
if (InputBox.Show(settings, out results)) {
    MessageBox.Show(string.Format("You wrote \"{0}\", \"{1}\", \"{2}\" and \"{3}\".", results));
}

Some of these InputValue subclasses provide some options for configuring the input elements. Please refer to the API reference to find out which properties are available.

If the pre-defined value types are not sufficient, you can also define some additional custom value types. You need to perform two steps to do so:

  • Define your own subclass of CustomValue<TValue>. Indicate the type of your value in the generic argument, and add any settings for the input elements to your settings.
  • In all GUI toolkit bindings that are supposed to support the additional input value type, use an overload of the Show method (exemplarily linking to the Gtk# version) that accepts a factory function that can, based on the input value object, create the respective GUI elements.

As in any user input scenario, sometimes some of the values supplied by the user have to be considered invalid. That is why the value input framework of the Two-Layered GUI Toolkit provides some means of validating input and indicating error messages if the input was found to be invalid.

The types related to input value validation are located in the TwoLayeredGUI.ValueInput.Validators namespace. Therefore, it is a good idea to add this namespace to your using directives now:

using TwoLayeredGUI.ValueInput.Validators;

An input value validator is an object of (a subclass of) the type ValueValidator<TValue>. The generic argument must match the data type of the input value.

As an example, let's impose some length restrictions on a string. (The StringValue is now given its own variable to make things a bit more readable.)

StringValue val = new StringValue(new AccessString("Validated value:", 'v'),
                                  new StringLengthValidator(3, 10));

InputBoxSettings settings = new InputBoxSettings();
settings.Title = "Value Input";
settings.Values.Add(val);
object[] results;
if (InputBox.Show(settings, out results)) {
    MessageBox.Show(string.Format("You wrote \"{0}\".", results[0]));
}

If you try this, you will notice that the input box cannot be closed any more unless your string has a length of at least 3 and at most 10 characters. If you do not like the default validation error message, use the properties of the StringLengthValidator class to modify it.

Of course, you can add more than one validator at a time for a given input value:

StringValue val = new StringValue(new AccessString("Validated value:", 'v'),
                                  new StringLengthValidator(3, 10),
                                  new RegexStringValidator("^A"));

Make sure, though, that you do not add any mutually exclusive validators. For example, users can never satisfy the requirements of two StringLengthValidator instances if one of them imposes a maximum length of 10 characters, and the other one requires a minimum length of 20 characters.

As the few pre-defined validators are certainly not sufficient for the specific needs in your custom application, feel free to subclass the ValueValidator<TValue> class and create your own validators.

This is not where the features of the value input framework in the Two-Layered GUI Toolkit stop, though: Input boxes are often with some additional means of selecting or computing values rather than manually entering them. Therefore, the TwoLayeredGUI.ValueInput.Commands namespace contains the EditValueCommand<T> class. Instances of its subclasses can be added to the EditCommands list of input values.

As a very simple example, an input box with the following input value contains a text box with a drop down menu that offers some pre-defined values:

string[] defaultValues = new[] { "Anna", "Brian", "Charlize", "Dexter" };
StringValue val = new StringValue(new AccessString("Value:", 'v'));
foreach (string defaultValue in defaultValues) {
    string currentValue = defaultValue;
    var cmd = new DelegateEditValueCommand<string>(
        delegate(ref string str) {
            if (MessageBox.Show(string.Format("Would you like to append \"{0}\" to your current string?",
                                              currentValue),
                                ButtonDef.YesNoButtons).Kind
                    == DefaultButtonKind.Yes) {
                str += currentValue;
                return true;
            } else {
                return false;
            }
        });
    cmd.DisplayName = new AccessString(currentValue);
    val.EditCommands.Add(cmd);
}

Once the user selects one of those menu items, he or she is asked for confirmation to append the respective string to the text in the text box.

You can of course show more elaborate dialogs in these commands (or none at all). Frequent examples could be a calculator dialog for numeric values, or a dictionary with recommended search terms.

Back / Continue


Related

Wiki: Help-Tutorial-Direct-MessageBoxes
Wiki: Help-Tutorial-Direct-Other
Wiki: Help-Tutorial-Direct-ProgressDialogs
Wiki: Help-Tutorial-Direct-WizardFramework
Wiki: Help-Tutorial-Direct
Wiki: Help-Tutorial-SettingsObjects-Other

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.