1

I'm currently trying to create a search filter for an application in C#. I have the following code:

loanerListBox1.Items.Clear();
string[] recordsRetreivedTemp = new string[recordsRetreived.Count];
recordsRetreived.CopyTo(recordsRetreivedTemp);
string pattern = loanerTextBox21.Text;
{
    foreach (string s in recordsRetreivedTemp)
    {
        if (System.Text.RegularExpressions.Regex.IsMatch(s, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase))
        {
            loanerListBox1.Items.Add(s);
        }
    }
}

I've noticed that after doing this a datatable of mine appears to not fill correctly. The connection string is fine, I've checked the query string and it appears to build just fine. I can't see where a problem could be.

SQL adapter code:

//retreive data
SqlDataAdapter adapter = new SqlDataAdapter(querystring, loanersConnection);
DataTable datatable = new DataTable();
adapter.Fill(datatable);
Items = new string[length, datatable.Rows.Count];
if (selectedTab == "LoanerItems")
{
    for (int x = 0; x <= length - 1; x++)
    {
        for (int y = 0; y <= datatable.Rows.Count - 1; y++)
        {
            Items[x, y] = datatable.Rows[y][ColumnLists.LoanerItems[x]] as String;
        }
    }
}

The error itself is an IndexOutOrRange exception as no values are contained within the Items array and the program attempts to iterate through the array in order to populate further textboxes.

I can provide any other code if need be. I'm only giving the basics right now.

EDIT:

To clarify. Things only break if I use the search filter. Everything appears to work fine before using it.

EDIT 2:

I've also checked to make sure the selectedTab variable is working properly. It's set right so the problem shouldn't be there. As I've said the query string builds properly and looks like "SELECT * FROM table WHERE column = value". The application connects to the database just fine but the datatable only appears to fill if I haven't used the search filter.

The datatable appears not to be filled as the following:

        for (int y = 0; y <= datatable.Rows.Count - 1; y++)
        {
            Items[x, y] = datatable.Rows[y][ColumnLists.LoanerItems[x]] as String;
        }

Is skipped over each time since there are zero rows in the datatable.

EDIT 3:

The listbox_selectionchanged method used to initialize the class using the sql adapter:

    private void loanerListBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (loanerListBox1.SelectedItem != null)
        {   //populate textboxes
            string comboBoxTemp1 = loanerComboBox1.SelectedItem.ToString();
            string comboBoxTempFinal = comboBoxTemp1.Replace(" ", string.Empty);
            string listBoxTemp = loanerListBox1.SelectedItem.ToString();
            string whereClause = string.Format("{0} = '{1}'", comboBoxTempFinal, listBoxTemp);

            SQLRetrieve.PopulateColumns populatecolumns = new SQLRetrieve.PopulateColumns(whereClause, tab);
            retreivedColumnsForWrite = populatecolumns.RetrieveColumns();
            populateLoanerItemsPage();

            //populate duplicates combobox
            loanerComboBox2.Items.Clear();
            for (int y = 0; y < retreivedColumnsForWrite.GetLength(1); y++)
            {
                if (!loanerComboBox2.IsEnabled)
                {
                    loanerComboBox2.IsEnabled = true;
                }
                string tobuild = "";

                //see note up top on retreivedColumnsForWrite array
                for (int x = 1; x < retreivedColumnsForWrite.GetLength(0); x++)
                {
                    tobuild += retreivedColumnsForWrite[x, y];
                    tobuild += "|";
                }

                loanerComboBox2.Items.Add(tobuild);
            }
            if (loanerComboBox2.Items.Count == 1)
            {
                loanerComboBox2.IsEnabled = false;
            }
        }

    }

Entire class using the SQl adapter:

public class PopulateColumns
{
    //Retreived columns via search query.
    //X is columns, y is rows.
    //Read through each x value for y row.
    //Not through each y value for x row.
    //for (y = 0; y < ?; y++)
        //for (x = 0; x <?; x++)
    private string[,] Items;
    private string querystring;
    private string selectedTab;
    private int length;

    public PopulateColumns(string passedString, string selectedTab)
    {
        //builds query string
         querystring = string.Format("SELECT * FROM {0} WHERE {1}", selectedTab, passedString);
        this.selectedTab = selectedTab;
        if (selectedTab == "LoanerItems")
        {
            length = 30;
        }
        else if (selectedTab == "Customers")
        {
            length = 16;
        }
    }

    public String[,] RetrieveColumns()
    {
        //Open Connection
        SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
        scsb.DataSource = "LLOYD2\\";
        scsb.InitialCatalog = "LoanersTest";
        scsb.IntegratedSecurity = true;
        scsb.ConnectTimeout = 30;

        SqlConnection loanersConnection = new SqlConnection(scsb.ConnectionString);

        //retreive data
        SqlDataAdapter adapter = new SqlDataAdapter(querystring, loanersConnection);
        DataTable datatable = new DataTable();
        adapter.Fill(datatable);
        Items = new string[length, datatable.Rows.Count];
        //New one needs to be added per tab.
        if (selectedTab == "LoanerItems")
        {
            for (int x = 0; x <= length - 1; x++)
            {
                for (int y = 0; y <= datatable.Rows.Count - 1; y++)
                {
                    Items[x, y] = datatable.Rows[y][ColumnLists.LoanerItems[x]] as String;
                }
            }
        }
        else if (selectedTab == "Customers")
        {
            for (int x = 0; x <= length - 1; x++)
            {
                for (int y = 0; y <= datatable.Rows.Count - 1; y++)
                {
                    Items[x, y] = datatable.Rows[y][ColumnLists.Customers[x]] as String;
                }
            }
        }

        return Items;
    }
}

Upon closer examination it would appear that a textbox.clear(); was causing the error here:

private void loanerComboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        loanerListBox1.Items.Clear();
        ***loanerTextBox21.Clear();***
        if (loanerComboBox1.SelectedItem != null)
        {
            Combox1Retrieve retriever = new Combox1Retrieve(loanerComboBox1.SelectedItem.ToString(), tab);
            recordsRetreived = retriever.retrieveSQL();
            for (int i = 0; i <= recordsRetreived.Count - 1; i++)
            {
                if (!loanerListBox1.Items.Contains(recordsRetreived[i]))
                {
                    loanerListBox1.Items.Add(recordsRetreived[i]);
                }
            }
        }
    }
DanteTheEgregore
  • 1,530
  • 5
  • 23
  • 44
  • How is the 'length' variable that you are using in your for loop set? It might be an off-by-one error with it. – ajawad987 Jun 12 '13 at 18:38
  • @ajawad987 ` if (selectedTab == "LoanerItems") { length = 30; } else if (selectedTab == "Customers") { length = 16; }` It should theoretically never change. – DanteTheEgregore Jun 12 '13 at 18:39
  • @ajawad987 I've also checked to make sure the selectedTab variable is working properly. It's set right so the problem shouldn't be there. As I've said the query string builds properly and looks like "SELECT * FROM _table_ WHERE _column_ = _value_". The application connects to the database just fine but the datatable only appears to fill if I haven't used the search filter. – DanteTheEgregore Jun 12 '13 at 18:43
  • Looks like more of the code in its entirety is needed to figure out what's really happening. – ajawad987 Jun 12 '13 at 18:52
  • Showing how the event handlers are wired up to the filtering logic and database loading code you show above would help. It could be that the creation of the data table you have is messing up since the database code clears a list box control, thus it doesn't have any data to work with until the database logic finishes. – ajawad987 Jun 12 '13 at 19:00

1 Answers1

0

Turns out that the the SelectionChanged events and the like I was using in the program all fire mistakenly. Under each method I implemented the following

if (e.Source is TabControl)
{
  //do work when tab is changed
}

Thanks to John Kragh's answer found here: Is there Selected Tab Changed Event in the standard WPF Tab Control

Community
  • 1
  • 1
DanteTheEgregore
  • 1,530
  • 5
  • 23
  • 44