Problem with WPF ListBox

G

Gordon Padwick

I'm in the process of attempting to climb the steep WPF learning cliff
(using Visual Studio 2008) and have run into a problem with displaying a
count of the number of items in a WPF ListBox.

My application displays data from an Access database in a ListBox within a
Grid. In markup, the ListBox defiinition contains:
Name = "familyList"
ItemsSource = "{Binding Path = familyData}"
ItemTemplate = "{StaticResource = FamilyTemplate}"

The Window element contains:
Loaded = "GetData"

Code behind contains the GetData method that consists of the usual C#
statements to connect to the database table and ends with the statements
myDataSet = new DataSet();
myAdapter.Fill(myDataSet, "familyData");
numFamily.Text = familyList.Items.Count.ToString();

numFamily is the name of a TextBox.

The application builds okay and runs okay as far as displaying database
items in the ListBox. However, the TextBox always display 0 (zero) despite
many items being listed.

The problem seems to be that the Count statement is executed before the
ListBox is filled, even though that satement occurs after the Fill statement
in the GetData method.

So, my question is: How can I get a count of the number of items in the
ListBox and display that number in a TextBox under the ListBox? I hope I've
provided enough information to enable someone to answer this question.

Thanks for any help offered.

Gordon Padwick
 
P

Peter Duniho

[...]
Code behind contains the GetData method that consists of the usual C#
statements to connect to the database table and ends with the statements
myDataSet = new DataSet();
myAdapter.Fill(myDataSet, "familyData");
numFamily.Text = familyList.Items.Count.ToString();

numFamily is the name of a TextBox.

The application builds okay and runs okay as far as displaying database
items in the ListBox. However, the TextBox always display 0 (zero)
despite many items being listed.

The problem seems to be that the Count statement is executed before the
ListBox is filled, even though that satement occurs after the Fill
statement in the GetData method.

Right. I'm no WPF expert, but I believe that the database query occurs
asynchronously, so all the Fill() method does is start things going. By
the time the next statement is executed, it hasn't actually had time to
update the ListBox at all, so the Count is still 0.
So, my question is: How can I get a count of the number of items in the
ListBox and display that number in a TextBox under the ListBox? I hope
I've provided enough information to enable someone to answer this
question.

You should subscribe to the
familyList.Items.ItemCollection.PropertyChanged event and watch for the
Count property to be changed, updating your TextBox any time it does.

Pete
 
G

Gordon Padwick

Thanks for the suggestion.

Being fairly new to WPF, I don't understand exactly what you mean by
"subscribe to..." I hope you can explain in more detail.

Gordon

Peter Duniho said:
[...]
Code behind contains the GetData method that consists of the usual C#
statements to connect to the database table and ends with the statements
myDataSet = new DataSet();
myAdapter.Fill(myDataSet, "familyData");
numFamily.Text = familyList.Items.Count.ToString();

numFamily is the name of a TextBox.

The application builds okay and runs okay as far as displaying database
items in the ListBox. However, the TextBox always display 0 (zero)
despite many items being listed.

The problem seems to be that the Count statement is executed before the
ListBox is filled, even though that satement occurs after the Fill
statement in the GetData method.

Right. I'm no WPF expert, but I believe that the database query occurs
asynchronously, so all the Fill() method does is start things going. By
the time the next statement is executed, it hasn't actually had time to
update the ListBox at all, so the Count is still 0.
So, my question is: How can I get a count of the number of items in the
ListBox and display that number in a TextBox under the ListBox? I hope
I've provided enough information to enable someone to answer this
question.

You should subscribe to the
familyList.Items.ItemCollection.PropertyChanged event and watch for the
Count property to be changed, updating your TextBox any time it does.

Pete
 
P

Peter Duniho

Thanks for the suggestion.

Being fairly new to WPF, I don't understand exactly what you mean by
"subscribe to..." I hope you can explain in more detail.

Sorry...that's just another way of describing adding an event handler to
an event.

For example:

familyList.Items.PropertyChanged += (sender, e) =>
{
if (e.PropertyName == "Count")
{
numFamily.Text = familyList.Items.Count.ToString();
}
};

Hope that helps.

Pete
 
G

Gordon Padwick

You still have me at a loss. As quite new to WPF, I don't understand the
code you're suggesting. The => makes it look like a lamda expression, but
I'm not yet up to dealing with lamdas. If you have the time, could you
please explain in more detail.

Thanks a lot.

Gordon
 
P

Peter Duniho

You still have me at a loss. As quite new to WPF, I don't understand the
code you're suggesting. The => makes it look like a lamda expression,
but I'm not yet up to dealing with lamdas. If you have the time, could
you please explain in more detail.

Yes, it's a lambda expression. One of the things lambda expressions do is
allow you to define an anonymous method.

Here are a couple of equivalents to the code I posted earlier:

familyList.Items.PropertyChanged += delegate(object sender,
PropertyChangedEventArgs e)
{
if (e.PropertyName == "Count")
{
numFamily.Text = familyList.Items.Count.ToString();
}
};

Or:

void SomeMethodOrConstructor()
{
familyList.Items.PropertyChanged += familyList_PropertyChanged;
}

// This method could be named anything, as long as you use the same
name
// above. I'm simply following the VS Designer's naming pattern here
void familyList_PropertyChanged(object sender,
PropertyChangedEventArgs e)
{
if (e.PropertyName == "Count")
{
numFamily.Text = familyList.Items.Count.ToString();
}
}

The bottom line here: the right way to deal with updating your
TextBox.Text property, which is supposed to display the number of items in
your ListBox.Items collection, is to add an event handler to the
PropertyChanged event in your ListBox.Items collection, looking for the
change to the Count property in that collection. Then when the value does
change, you immediately change the text of the TextBox to reflect that.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top