0

I populate my ListBox with a Binding to an ObservableCollection. The items are added to the ListBox just fine, but when I want to select the first item of the ListBox I get an InvalidOperationException...

Code:

private void PopulateDateListbox()
{
    // clear listbox
    DateList.Clear();

    // get days in month
    int days = DateTime.DaysInMonth(currentyear, currentmonth);

    // new datetime
    DateTime dt = new DateTime(currentyear, currentmonth, currentday);

    for (int i = 0; i < (days-currentday+1); i++)
    {
        // create new dataitem
        DateItem di = new DateItem();
        di.dayint = dt.AddDays(i).Day.ToString(); // day number
        di.day = dt.AddDays(i).DayOfWeek.ToString().Substring(0, 3).ToUpper(); // day string
        di.monthint = dt.AddDays(i).Month.ToString(); // month number
        di.yearint = dt.AddDays(i).Year.ToString(); // year number

        // add dateitem to view
        Dispatcher.BeginInvoke(() => DateList.Add(di));
    }

    // select first item in Listbox
    datelistbox.SelectedIndex = 0; // <= InvalidOperationException
}

I also tried:

datelistbox.SelectedItem = datelistbox.Items.First();

Neither works and I don't know why?

3
  • Do you call PopulateDateListbox in worker thread(other than UI thread)? Commented Aug 19, 2013 at 12:29
  • PopulateDateListbox gets called in the page=loaded eventhandler. Commented Aug 19, 2013 at 12:30
  • Post the error message you're getting Commented Aug 19, 2013 at 12:31

2 Answers 2

1

The same way you're using the dispatcher to add new items, use it to change the selected item:

Dispatcher.BeginInvoke(() => datelistbox.SelectedIndex = 0);
Sign up to request clarification or add additional context in comments.

3 Comments

Oh I see.. I normaly get UnauthorizedException for things like this! Thank you.
@PhilippeMaes That's because it's not a cross-thread access. Since you're using the dispatcher to add the elements to the list, and since PopulateDateListbox is executing on the UI thread (you said you're calling it from the page_load event handler), the items won't be added until the method has finished executing. So you're trying to select an item that has yet to be added. The best solution would be to remove all calls to dispatcher altogether.
I see. Sometimes its not easy to know when I have to use a dispatcher or not. But I'm still learning!
1

Dispatcher calls are asynchronous have no guarantee for when they'll run, so when you set the selected index, that item doesn't exist yet. Consolidate all UI-based work into a single call -

List<DateItem> items = new List<DateItem>();
for (int i = 0; i < (days-currentday+1); i++)
   // Create your items and add them to the list
Dispatcher.BeginInvoke(() =>
{
   DateList.ItemsSource = items;
   DateList.SelectedIndex = 0;
});

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.