Reputation: 339
Hi I would like to create a dynamic generic input box function which allows the user to select an input from a list of inputs and then return this. For the list of Items I want to use a dictionary.
For the declaration I was thinking along the lines of the following:
public static DialogResult InputBox<KeyType, ValueType>(string aTitle, string aPromptText, Dictionary<KeyType, ValueType> aDictionary, ref KeyValuePair<KeyType, ValueType> aReturnPair)
I already have two similar functions, one for dates and one for strings.
But I want to know is the dictionary one possible? How do I handle the casting? Do I have to pass the type of the key and value as well or can I retrieve this during run time?
Also is it possible to specify the "function" to use to retrieve the name to use for display For example I have the following struct:
public struct Person
{
public int Age;
public string Name;
public string Surname;
}
How can I tell the function to use Person.Surname for display purposes?
Example usage:
Dictionary<int, Person> Persons = new Dictionary<int,Person>();
KeyValuePair<int, Person> lPair= new KeyValuePair<int,Person>
DialogResult dialogResult = DialogResult.Cancel
While (dialogResult == DialogResult.Cancel)
{
dialogResult = CustomForm.InputBox<int, Person>("title", "prompt", Persons, ref lPair, Person.Surname);
}
String input function
public static DialogResult InputBox(string aTitle, string aPromptText, ref string aValue, Boolean aPassword = false )
{
Form lForm = new Form();
Label lLabel = new Label();
TextBox lTextBox = new TextBox();
Button lButtonOk = new Button();
Button lButtonCancel = new Button();
lForm.Text = aTitle;
lLabel.Text = aPromptText;
lTextBox.Text = aValue;
if (aPassword)
{
lTextBox.PasswordChar = '*';
}
lButtonOk.Text = "OK";
lButtonCancel.Text = "Cancel";
lButtonOk.DialogResult = DialogResult.OK;
lButtonCancel.DialogResult = DialogResult.Cancel;
lLabel.SetBounds(9, 20, 372, 13);
lTextBox.SetBounds(12, 36, 372, 20);
lButtonOk.SetBounds(228, 72, 75, 23);
lButtonCancel.SetBounds(309, 72, 75, 23);
lLabel.AutoSize = true;
lTextBox.Anchor = lTextBox.Anchor | AnchorStyles.Right;
lButtonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
lButtonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
lForm.ClientSize = new Size(396, 107);
lForm.Controls.AddRange(new Control[] { lLabel, lTextBox, lButtonOk, lButtonCancel });
lForm.ClientSize = new Size(Math.Max(300, lLabel.Right + 10), lForm.ClientSize.Height);
lForm.FormBorderStyle = FormBorderStyle.FixedDialog;
lForm.StartPosition = FormStartPosition.CenterScreen;
lForm.MinimizeBox = false;
lForm.MaximizeBox = false;
lForm.AcceptButton = lButtonOk;
lForm.CancelButton = lButtonCancel;
DialogResult dialogResult = lForm.ShowDialog();
aValue = lTextBox.Text;
return dialogResult;
}
Upvotes: 0
Views: 371
Reputation: 339
I managed to create one Here is the completed function
public static DialogResult InputBox<KeyType, ValueType>(string aTitle, string aPromptText, Dictionary<KeyType, ValueType> aDictionary, ref KeyValuePair<KeyType, ValueType> aReturnPair, Func<ValueType, string> aDelegate)
{
Form lForm = new Form();
Label lLabel = new Label();
ComboBox lComboBox = new ComboBox();
Button lButtonOk = new Button();
Button lButtonCancel = new Button();
lForm.Text = aTitle;
lLabel.Text = aPromptText;
foreach (KeyValuePair<KeyType, ValueType> lPair in aDictionary)
{
lComboBox.Items.Add(aDelegate(lPair.Value));
}
lButtonOk.Text = "OK";
lButtonCancel.Text = "Cancel";
lButtonOk.DialogResult = DialogResult.OK;
lButtonCancel.DialogResult = DialogResult.Cancel;
lLabel.SetBounds(9, 20, 372, 13);
lComboBox.SetBounds(12, 36, 372, 20);
lButtonOk.SetBounds(228, 72, 75, 23);
lButtonCancel.SetBounds(309, 72, 75, 23);
lLabel.AutoSize = true;
lComboBox.Anchor = lComboBox.Anchor | AnchorStyles.Right;
lButtonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
lButtonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
lForm.ClientSize = new Size(396, 107);
lForm.Controls.AddRange(new Control[] { lLabel, lComboBox, lButtonOk, lButtonCancel });
lForm.ClientSize = new Size(Math.Max(300, lLabel.Right + 10), lForm.ClientSize.Height);
lForm.FormBorderStyle = FormBorderStyle.FixedDialog;
lForm.StartPosition = FormStartPosition.CenterScreen;
lForm.MinimizeBox = false;
lForm.MaximizeBox = false;
lForm.AcceptButton = lButtonOk;
lForm.CancelButton = lButtonCancel;
DialogResult dialogResult = lForm.ShowDialog();
if ((dialogResult == DialogResult.OK) && (lComboBox.SelectedIndex > -1) && (lComboBox.SelectedIndex < aDictionary.Count))
{
foreach (KeyValuePair<KeyType, ValueType> lPair in aDictionary)
{
if (string.Compare(aDelegate(lPair.Value),lComboBox.Items[lComboBox.SelectedIndex].ToString())== 0)
{
aReturnPair = lPair;
}
}
}
return dialogResult;
}
You call it as follows:
DialogResult dialogResult = CustomForm.InputBox<int, Person>("title", "prompt", Persons, ref lPair, (Person) => Person.Name);
Upvotes: 0
Reputation: 327
You can use delegates function that take a dictionary as parameter and return a string to the user, something like this:
Func<Dictionary<Object, Object>,string> userOutput
By adding this parameter to the function you can write the logic of casting and how you want to prompt the output to the user, you call it like this:
txtTextBox.Text = userOutput(dictionary);
Upvotes: 2