My WPF MVVM VB.NET app loads a list of songs into a ListBox at start. The list contents populate in a BackgroundWorker that is kicked off in the Constructor of the ViewModel. Once this is done, I want to set focus to the first song in the list.
As setting this focus is purely a View operation, I want it in the code-behind of the XAML. It's no business of the ViewModel where focus goes.
I tried doing this on various Window and ListBox events, but they either don't fire, or fire too early. So I'm think what I need is a Boolean Property that the ViewModel sets when it's done loading the songs into the list. That's when I need the View to catch that Property Change, and call the code-behind function that has the logic to maniuplate the View, in the is case, setting focus on the first song in the list.
But this is where my knowledge of WPF is short. I searched and it sounds like DataTrigger could do the trick. But where to put it, and what's the right syntax, and how to have it call my code-behind function?
Or is there an even simpler way that I'm overlooking. This seems like a basic functionality - to trigger some code-behind action in the View when a Property changes a certain way in the ViewModel.
Here's the code-behind function. I can elaborate it once it's successfully getting called at the intended time:
Private Sub FocusSongsList()
' set focus back to the Songs list, selected item (couldn't just set focus to the list, it ran forever and looks like it set focus to every item in turn before releasing the UI)
Dim listBoxItem = CType(LstSongs.ItemContainerGenerator.ContainerFromItem(LstSongs.SelectedItem), ListBoxItem)
If Not listBoxItem Is Nothing Then
listBoxItem.Focus()
End If
End Sub
Here's my ListBox:
<ListBox x:Name="LstSongs" ItemsSource="{Binding FilteredSongs}" DisplayMemberPath="Path"
HorizontalAlignment="Stretch"
SelectionMode="Extended" SelectionChanged="LstSongs_SelectionChanged" Loaded="FocusSongsList"/>
And I would define a new property that can be set from the RunWorkerCompleted part of the BackgroundWorker.
Private _InitialSongLoadCompleted As Boolean
Public Property InitialSongLoadCompleted() As Boolean
Get
Return _InitialSongLoadCompleted
End Get
Set(ByVal value As Boolean)
_InitialSongLoadCompleted = value
RaisePropertyChanged("InitialSongLoadCompleted")
End Set
End Property