I've seen this question asked numerous times and have gone over my code over and over. But when I assign to my SelectedItem-bound property with an object, it does not update the display's selected item. It appears that the ListBox thinks the object I assign is not a member of its items.
public class MainViewModel : ViewModelBase
{
//...
public SortedObservableCollection<TubeViewModel> Items { get; private set; }
public TubeViewModel SelectedTube { //get, set, propertychanged, etc. }
}
<ListBox x:Name="TubeList"
Margin="10"
ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource TubeTemplate}"
SelectedItem="{Binding SelectedTube, Mode=TwoWay}"
SelectionMode="Single"
VirtualizingStackPanel.IsVirtualizing="False">
</ListBox>
Here's the impl from one of the places where I try to set SelectedTube - definitely occurs on the main thread.
var match =
from t in Items
where t.Model.DataFileName == filename
select t;
if (match.Any())
SelectedTube = match.First();
I was noticing that the SelectedTube was never highlighted unless I manually clicked on it, but kind of ignored it. But then I wanted to ScrollIntoViewCentered the selected item, so I added a DependencyProperty in my view to watch for SelectedItem changes. The handler initially looked like so:
private void OnSelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
if (TubeList.SelectedItem == null)
return;
TubeList.ScrollIntoViewCentered(TubeList.SelectedItem);
}
But didn't work if I set the SelectedItem through my binding. After deciding I wanted to only scroll it if it was not on screen, I changed the code to this:
private void OnSelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
if (TubeList.SelectedItem == null)
return;
var container = TubeList.ItemContainerGenerator.ContainerFromItem(TubeList.SelectedItem) as FrameworkElement;
if(!container.IsVisible)
TubeList.ScrollIntoViewCentered(TubeList.SelectedItem);
}
If SelectedItem is externally set, container is null. Every time. I even added code to check for null and then iterate over the ItemsSource looking for a filename match, then update SelectedItem to make sure SelectedItem was definitely an object in the listbox. No luck.
It's not a visibility thing, if the item is on screen, it still doesn't highlight. Do I need to implement some sort of equality function? I've wasted more time than one might think possible on this.
thanks.