views:

17

answers:

1

I looked at several related answers, and determined that I can programmatically clear the selection by setting lstData.SelectedIndex = -1; However, when I do it right after setting the data context on startup, somehow it never works and gets set to select the first element in the list.

I also tried adding the setting to the XAML, and -1 is actually Visual Studio's default value, though it isn't actually in the XAML unless you set it. I.e.:

    <ListView Margin="6,6,6,203" 
        IsSynchronizedWithCurrentItem="True" 
        x:Name="lstData" 
        ItemsSource="{Binding}" 
        SelectionChanged="lstData_SelectionChanged" 
        HorizontalContentAlignment="Right"
        ItemContainerStyle="{StaticResource ItemContStyle}"  
        SelectedIndex="-1">

But this also has no effect.

Also, fascinatingly, if I put lstData.SelectedIndex = 3; in my LoadData method, it WILL start set with the third member selected.

This is my relevant window loading code:

    public Window1()
    {
        InitializeComponent(); 

        // Set start and end dates to day after tomorrow, and 
        // the next day, by default:
        StartDate = DateTime.Now.AddDays(1);
        EndDate = StartDate.AddDays(2);
        txtStartDate.Text = StartDate.ToShortDateString();
        txtEndDate.Text = EndDate.ToShortDateString();
        LoadData();
    }

    public void LoadData()
    {
        App.RefreshMembers();

        App.CalculateNeededMeals(StartDate, EndDate);

        // Bind the ListBox to our ObserveableCollection
        LayoutRoot.DataContext = 
          App.db.PFW_Members.OrderBy("FullName",true).OrderBy("CancelDate",true);
        lstData.SelectedIndex = -1;
    }

And LoadData() gets called in other circumstances, and in that case it DOES clear the selection. Just not the first time the window loads. As if, there is some initialization thread that is not really finished and goes and sets the selection to 0 if it is -1 on startup.

Oh and yes I do have a selection changed handler, but it doesn't change the selection, i.e.:

    private void lstData_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (lstData.SelectedItem == null)
        {
            btnReactivate.IsEnabled = false;
            btnDeactivate.IsEnabled = false;
        }
        else
        {
            if (((PFW_Member)lstData.SelectedItem).CancelDate == null)
            {
                btnReactivate.IsEnabled = false;
                btnDeactivate.IsEnabled = true;
            }
            else
            {
                btnReactivate.IsEnabled = true;
                btnDeactivate.IsEnabled = false;
            }
        }
    }

Is there some way to make it really wait until loaded, and then do stuff, or to set a delayed event or something, or does someone have knowledge or a theory about what might be going on here?

Thanks for any tips!

A: 

Just set IsSynchronizedWithCurrentItem="False". This will be the easiest way to fix it.

What's happening here is this: after everything gets Initialized (i.e. after the constructor), the Bindings will kick in. The ListBox's ItemsSource will be set at this time. During this step, some ICollectionView magic happens behind the scenes. Essentially, the ListBox will get connected to the source collection's default CollectionView, whose CurrentItem property always defaults to the first item. Now, if IsSynchronizedWithCurrentItem is true, the ListBox will update the SelectedItem to be equal to the ICollectionView.CurrentItem. This is what's causing the issue you mentioned.

(Note: after all of these happens, the Loaded event will get fired. So, dnr3's comment of setting the SelectedIndex=-1 in the Loaded event should also work).

Hope this makes sense.

karmicpuppet
Aha! That works. Thanks so much for the solutions and explanation! (I tried to mark this as useful, but my reputation isn't 15 yet.)
Dronz
Not a problem. Maybe mark it sometime in the future. (Or not). ;)
karmicpuppet