HELP!! ListBox_SelectedIndexChanged

  • Thread starter Thread starter jez
  • Start date Start date
J

jez

I've got a ListBox and a DataGrid. Both use different DataTables (both
DataTables are connected with a DataRelation : Parent<->Child).

ListBox uses customersTable
DataGrid uses productsTable

When I click on an entry in the ListBox the ListBox_SelectedIndexChanged
event is called that fires one of my methods that refreshes the DataGrid and
filters out all the products that do not belong to the customer that was
clicked (I do that using a filter on the customerID in the DataGrid).

It works fine only that I need to click twice on an entry in the ListBox for
my DataGrid to be refreshed. In other words, it seems like the
ListBox_SelectedIndexChanged has to be fired twice so that my DataGrid is
refreshed properly.

I tried to be clever (and it didn't work..) and included my method twice in
ListBox_SelectedIndexChanged to see what happens - still same problem. I
actually need to click twice on ListBox item so that my DataGrid is updated.
What is interesting though is that after clicking it once some of the other
items (for example labels) _are_ updated!

Does anyone have any clue as to what I should do ?

Thanks!
 
It sounds like there might be a bug in your ListBox_SelectedIndexChanged
method. If the labels always update properly after selecting a new listbox
item, then that's not where your problem is.
 
Ginny,

thanks for your reply. I had a look at the method, I cut it down a bit but
still can't figure out how to solve it. I know I do know where the problem
lies, though.

Basically (after using MessageBox.Show(customerID)) I realised that the
label with the customerID only gets updated at the end of the
listBoxCustomers_SelectedIndexChanged method. This means that when I refresh
the DataGrid it naturally gets the old customerID value. Therefore I created
a second method that does that update of the customerID label before
refreshing the DataGrid - without luck.

Do labels wait until all the methods are finished before being refreshed? Or
do I need to put a one second delay between the update of the label and the
refreshment of the DataGrid ?

I copied the two methods below that are executed when the
listBoxCustomers_SelectedIndexChanged event is fired. updateCustomerID is
first executed, followed by refreshProductsDataGrid.

Thanks heaps!

private void updateCustomerID()
{
DataTable customersTable = _CustomersDS.Tables["customersTable"];
lblCustomerIDFromList.DataBindings.Clear();
lblCustomerIDFromList.DataBindings.Add("Text", customersTable,
"customerID");
lblCustomerIDFromList.Refresh();
MessageBox.Show("CustomerID in STRING:
"+lblCustomerIDFromList.Text.ToString());
}

private void refreshProductsDataGrid()
{
string stringCurrentCustomerID = lblCustomerIDFromList.Text.ToString();
int currentCustomerID = Convert.ToInt32(stringCurrentCustomerID);
DataView filteredDataView = new
DataView(_CustomersDS.Tables["productsTable"],
"customerID="+currentCustomerID, "products", DataViewRowState.CurrentRows);
dataGridProducts.DataSource=null;
dataGridProducts.DataSource = filteredDataView;
dataGridProducts.Refresh();
}
 
jez,

If you update the text in a label programmatically, the label should then
have that text value even if it doesn't display it yet (because it hasn't
repainted itself). If you try updating the label's text directly rather than
using data binding, do you get the same result? In any case, I don't think
the issue is that your SelectedIndexChanged event isn't firing properly,
which I think you agree with now. So maybe the issue is the way data binding
works compared with how one might expect it to work.
--
Ginny Caughey
..Net Compact Framework MVP

jez said:
Ginny,

thanks for your reply. I had a look at the method, I cut it down a bit but
still can't figure out how to solve it. I know I do know where the problem
lies, though.

Basically (after using MessageBox.Show(customerID)) I realised that the
label with the customerID only gets updated at the end of the
listBoxCustomers_SelectedIndexChanged method. This means that when I refresh
the DataGrid it naturally gets the old customerID value. Therefore I created
a second method that does that update of the customerID label before
refreshing the DataGrid - without luck.

Do labels wait until all the methods are finished before being refreshed? Or
do I need to put a one second delay between the update of the label and the
refreshment of the DataGrid ?

I copied the two methods below that are executed when the
listBoxCustomers_SelectedIndexChanged event is fired. updateCustomerID is
first executed, followed by refreshProductsDataGrid.

Thanks heaps!

private void updateCustomerID()
{
DataTable customersTable = _CustomersDS.Tables["customersTable"];
lblCustomerIDFromList.DataBindings.Clear();
lblCustomerIDFromList.DataBindings.Add("Text", customersTable,
"customerID");
lblCustomerIDFromList.Refresh();
MessageBox.Show("CustomerID in STRING:
"+lblCustomerIDFromList.Text.ToString());
}

private void refreshProductsDataGrid()
{
string stringCurrentCustomerID = lblCustomerIDFromList.Text.ToString();
int currentCustomerID = Convert.ToInt32(stringCurrentCustomerID);
DataView filteredDataView = new
DataView(_CustomersDS.Tables["productsTable"],
"customerID="+currentCustomerID, "products", DataViewRowState.CurrentRows);
dataGridProducts.DataSource=null;
dataGridProducts.DataSource = filteredDataView;
dataGridProducts.Refresh();
}
 
Ginny,

By "directly" you mean using lblcustomerID.text="007" ? Is there any way I
can automatically change a label without databinding ?

There's the ListBox that selects a customer and since the customerID is
bound to the listBox the customerID label also changes automatically.
Wouldn't mind trying to update the customerID label another way, just don't
know how..

jez

Ginny Caughey said:
jez,

If you update the text in a label programmatically, the label should then
have that text value even if it doesn't display it yet (because it hasn't
repainted itself). If you try updating the label's text directly rather than
using data binding, do you get the same result? In any case, I don't think
the issue is that your SelectedIndexChanged event isn't firing properly,
which I think you agree with now. So maybe the issue is the way data binding
works compared with how one might expect it to work.
--
Ginny Caughey
.Net Compact Framework MVP

jez said:
Ginny,

thanks for your reply. I had a look at the method, I cut it down a bit but
still can't figure out how to solve it. I know I do know where the problem
lies, though.

Basically (after using MessageBox.Show(customerID)) I realised that the
label with the customerID only gets updated at the end of the
listBoxCustomers_SelectedIndexChanged method. This means that when I refresh
the DataGrid it naturally gets the old customerID value. Therefore I created
a second method that does that update of the customerID label before
refreshing the DataGrid - without luck.

Do labels wait until all the methods are finished before being
refreshed?
Or
do I need to put a one second delay between the update of the label and the
refreshment of the DataGrid ?

I copied the two methods below that are executed when the
listBoxCustomers_SelectedIndexChanged event is fired. updateCustomerID is
first executed, followed by refreshProductsDataGrid.

Thanks heaps!

private void updateCustomerID()
{
DataTable customersTable = _CustomersDS.Tables["customersTable"];
lblCustomerIDFromList.DataBindings.Clear();
lblCustomerIDFromList.DataBindings.Add("Text", customersTable,
"customerID");
lblCustomerIDFromList.Refresh();
MessageBox.Show("CustomerID in STRING:
"+lblCustomerIDFromList.Text.ToString());
}

private void refreshProductsDataGrid()
{
string stringCurrentCustomerID = lblCustomerIDFromList.Text.ToString();
int currentCustomerID = Convert.ToInt32(stringCurrentCustomerID);
DataView filteredDataView = new
DataView(_CustomersDS.Tables["productsTable"],
"customerID="+currentCustomerID, "products", DataViewRowState.CurrentRows);
dataGridProducts.DataSource=null;
dataGridProducts.DataSource = filteredDataView;
dataGridProducts.Refresh();
}

It sounds like there might be a bug in your ListBox_SelectedIndexChanged
method. If the labels always update properly after selecting a new listbox
item, then that's not where your problem is.
 
jez,
By "directly" you mean using lblcustomerID.text="007" ? Is there any way I
can automatically change a label without databinding ?

Yes, this is what I had in mind. You could write your own form of
databinding based on events, but this might be overkill. In one of my apps
some of the controls are bound to my own data objects, but those data
classes also have code to send notification back to the GUI whenever the
state of their data changes to perform other actions. I ended up writing a
bit more code than I expected, but now everything works the way I want. I
wouldn't use this approach in every app though. ;-)
There's the ListBox that selects a customer and since the customerID is
bound to the listBox the customerID label also changes automatically.
Wouldn't mind trying to update the customerID label another way, just don't
know how..

This sounds like a good approach to me too. But if it's not working the way
you want, then you have to look for workarounds. The best advice I can give
you is to try to find out why the databinding isn't working the way you
expect. If it looks like a .NetCF bug, be sure to let us know. And if looks
like just the way databinding is designed, then try some things to
workaround the limitation.

--
Ginny Caughey
..Net Compact Framework MVP

jez said:
Ginny,

By "directly" you mean using lblcustomerID.text="007" ? Is there any way I
can automatically change a label without databinding ?

There's the ListBox that selects a customer and since the customerID is
bound to the listBox the customerID label also changes automatically.
Wouldn't mind trying to update the customerID label another way, just don't
know how..

jez

jez,

If you update the text in a label programmatically, the label should then
have that text value even if it doesn't display it yet (because it hasn't
repainted itself). If you try updating the label's text directly rather than
using data binding, do you get the same result? In any case, I don't think
the issue is that your SelectedIndexChanged event isn't firing properly,
which I think you agree with now. So maybe the issue is the way data binding
works compared with how one might expect it to work.
--
Ginny Caughey
.Net Compact Framework MVP

jez said:
Ginny,

thanks for your reply. I had a look at the method, I cut it down a bit but
still can't figure out how to solve it. I know I do know where the problem
lies, though.

Basically (after using MessageBox.Show(customerID)) I realised that the
label with the customerID only gets updated at the end of the
listBoxCustomers_SelectedIndexChanged method. This means that when I refresh
the DataGrid it naturally gets the old customerID value. Therefore I created
a second method that does that update of the customerID label before
refreshing the DataGrid - without luck.

Do labels wait until all the methods are finished before being
refreshed?
Or
do I need to put a one second delay between the update of the label
and
the
refreshment of the DataGrid ?

I copied the two methods below that are executed when the
listBoxCustomers_SelectedIndexChanged event is fired. updateCustomerID is
first executed, followed by refreshProductsDataGrid.

Thanks heaps!

private void updateCustomerID()
{
DataTable customersTable = _CustomersDS.Tables["customersTable"];
lblCustomerIDFromList.DataBindings.Clear();
lblCustomerIDFromList.DataBindings.Add("Text", customersTable,
"customerID");
lblCustomerIDFromList.Refresh();
MessageBox.Show("CustomerID in STRING:
"+lblCustomerIDFromList.Text.ToString());
}

private void refreshProductsDataGrid()
{
string stringCurrentCustomerID = lblCustomerIDFromList.Text.ToString();
int currentCustomerID = Convert.ToInt32(stringCurrentCustomerID);
DataView filteredDataView = new
DataView(_CustomersDS.Tables["productsTable"],
"customerID="+currentCustomerID, "products", DataViewRowState.CurrentRows);
dataGridProducts.DataSource=null;
dataGridProducts.DataSource = filteredDataView;
dataGridProducts.Refresh();
}

It sounds like there might be a bug in your ListBox_SelectedIndexChanged
method. If the labels always update properly after selecting a new listbox
item, then that's not where your problem is.
 
Quick question before I go on with my ListBox problem..

It's about a select operation on a DataTable. I want to select a single row
(it's always going to be a single row because it comes from a selection from
a DataGrid) using the select operation and then delete it from the
DataTable. Why is it so complicated?:(

I manage to delete rows using the code below but only for my first customer,
for all subsequent customers I get an IndexOutOfRangeException. I know it's
because of that foundRows[0] Array but I can't figure out how to delete one
row in my DataTable. The foundRows[] will always only have one row. Any
ideas?

DataTable productsTable = _CustomersDS.Tables["productsTable"];
string selectString = "customerID="+currentCustomerID +" AND
product='productname'";
DataRow[] foundRows;
foundRows = productsTable.Select(selectString);
productsTable.Rows.Remove(foundRows[0]);
 
jez,

You should always check the return value of Select. In your code that
handles the condition where nothing was found, then you could determine why.
And even though you only expect to get one row found, it would also be a
good idea to handle the situation where this wasn't the case - perhaps due
to an error.
 
It seems to be working now.. allow me to reply to my own question (the one
related to deleting rows).

I was trying to locate a row using a string. For some reason (Ask Bill) the
string wasn't updated (probs my fault though) so all I did was take the
value of the customerID from the customerID label, that is without going
through the customerID string. Donno if anyone understood that but if you
want to know more I'll let you know.

still stuck with the ListBox and databinding though.. will see if can solve
it somehow.. any other hints are welcome as always:)
 
Back
Top