2
\$\begingroup\$

I have set up a Dictionary that calls on a class to fill a DataGridView via SQL statements. The problem is in two (out of 5) instances the value passed HAS to be an integer, but the value comes from a textbox so it is being passed as string. Before I set these Dictionaries up I was just using a switch statement that can be seen here. In my switch statement I simply added:

int n;
bool isNumber = int.TryParse(textBox.Text, out n);

if (!isNumber)
{
  MessageBox.Show("Input must be an integer");
  break;
}

to the two cases that needed the value to be an integer type.

Any idea on how I can add error handling to this? Preferably a message box that just says "value needs to be an integer".

    private void findScriptsQueryButton_Click(object sender, EventArgs e)
    {
        SqlConnection connection = new SqlConnection();
        string value = this.valueTextBox.Text;
        connection.ConnectionString = GetSqlConnection[serverComboBox.SelectedItem.ToString()];
        findScriptsDataGrid.DataSource = GetDataSource[findByComboBox.SelectedItem.ToString()](connection, value).Tables[0];
    }
    private static TableAdapters.FindScript dataSource = new TableAdapters.FindScript();
    private static readonly Dictionary<String, Func<SqlConnection, String, DataSet>> GetDataSource = new Dictionary<String, Func<SqlConnection, String, DataSet>>()
    {
        {"Target VDN", dataSource.FillByTargetVDN},
        {"Skill Group", dataSource.FillBySkillGroup},
        {"Translation Route Pool", dataSource.FillByTranslationRoutePool},
        {"Name", dataSource.FillByName},
        {"Label", dataSource.FillByLabel}
    };

    private static readonly Dictionary<String, String> GetSqlConnection = new Dictionary<String, String>()
    {
        {"SERVER01", ConfigurationManager.ConnectionStrings["csS01"].ConnectionString},
        {"SERVER02", ConfigurationManager.ConnectionStrings["csS02"].ConnectionString}
    };
\$\endgroup\$
5
  • \$\begingroup\$ Clarification on the text box: Does it have to be a text box? Or can you make it a different type of input? \$\endgroup\$
    – JohnP
    Commented Jul 3, 2014 at 15:06
  • \$\begingroup\$ In this case the text box will be the most efficient solution. It's used to pass a parameter to a query which can literally be hundreds of thousands of possible strings or integers. \$\endgroup\$ Commented Jul 3, 2014 at 15:11
  • \$\begingroup\$ If it can be hundreds of thousands, then how are you restricting it in only 2 of 5 instances? \$\endgroup\$
    – JohnP
    Commented Jul 3, 2014 at 15:17
  • \$\begingroup\$ "Target VDN" and "Skill Group" are the only two queries in the dictionary that REQUIRE an integer value. \$\endgroup\$ Commented Jul 3, 2014 at 15:25
  • 1
    \$\begingroup\$ Take a look at the ErrorProvider class. And the StackOverflow errorprovider tag \$\endgroup\$
    – radarbob
    Commented Jul 15, 2014 at 19:51

2 Answers 2

2
\$\begingroup\$

In your data structure include a validator (this should probably be a Predicate<String>); most of the predicates will just return true, but the two that require integers will have a nontrivial validator that checks for integer.

So I guess the type should be Dictionary<String, Tuple<Func<SqlConnection, String, DataSet>>,Predicate<String>>

\$\endgroup\$
2
\$\begingroup\$

I haven't tested, so cannot verify about errors but you could try something like this -

  1. Create validator functions for validating input -

    public bool DummyValidator(string input)
    {
    
        return true;
    }
    
    public bool ValidateIntegerInput(string input)
    {
        int n;
        bool isNumber = int.TryParse(input, out n);
    
        if (!isNumber)
        {
            MessageBox.Show("Input must be an integer");\
            return false;
        }
        return true;
    }
    
  2. Create dictionary to hold them -

    private static readonly Dictionary<String, Func<String, Boolean>> GetValidator = new Dictionary<String, Func<String, Boolean>>()
    {
        {"Target VDN", dataSource.ValidateIntegerInput},
        {"Skill Group", dataSource.ValidateIntegerInput},
        {"Translation Route Pool", dataSource.DummyValidator},
        {"Name", dataSource.DummyValidator},
        {"Label", dataSource.DummyValidator}
    };
    
  3. Then validate before calling methods -

    SqlConnection connection = GetSqlConnection();
    string value = this.ValueTextBox.Text;
    
    if (GetValidator[this.FindByComboBox.SelectedItem.ToString()](textBox.Text)){
    
        this.FindScriptsDataGrid.DataSource = switchReplacement[this.FindByComboBox.SelectedItem.ToString()](connection, value).Tables[0];
    
    }
    

You can map other validators accordingly.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.