Herman
Well-known member
I have a stupid problem, which seems it should have a solution implemented in the control itself, but I cannot figure out how to do it.
I have the following ListView bound to the window's view model:
Everything is bound nicely and everything works up to this point. However the view model has a timer running that periodically refreshes the CurrentSnapshot object. When it does, because the ViewModel implements INotifyPropertyChanged, the ItemsSource for the listview is refreshed, the new items are bound, and the existing selection is lost. Without MVVM I would likely have something like this:
And then I would RemoveHandler and AddHandler before and after assigning to the ItemsSource. I cannot see how I can do this while respecting the MVVM pattern however. I have seen some examples online, that suggest using an attached behavior and whatnot. Isn't there a simple and easy way to handle this without having to go dig through dependency properties?
Thank you.
I have the following ListView bound to the window's view model:
<ListView x:Name="lvItems" Grid.Row="0" Margin="0" FontSize="10" FontWeight="SemiBold" SelectionMode="Single" ItemsSource="{Binding CurrentSnapshot}"> <ListView.Resources> <ContextMenu x:Key="cmItemsContextMenu"> <MenuItem x:Name="miManageAlerts" Header="Manage Alerts..." /> </ContextMenu> </ListView.Resources> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Setter Property="ContextMenu" Value="{StaticResource cmItemsContextMenu}" /> </Style> </ListView.ItemContainerStyle> <ListView.View> <GridView> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding MachineName}" Header="Machine Name " /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding CpuUsagePercent}" Header="CPU Usage (%) " /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding DiskUsagePercent}" Header="HDD Usage (%) " /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding MemoryAvailableMB}" Header="Available Memory (MB) " /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding NetUsageInKBytesSec}" Header="Network In (KB/s) " /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding NetUsageOutKBytesSec}" Header="Network Out (KB/s) " /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding TerminalServicesSessions}" Header="# of Sessions " /> </GridView> </ListView.View> </ListView>
Everything is bound nicely and everything works up to this point. However the view model has a timer running that periodically refreshes the CurrentSnapshot object. When it does, because the ViewModel implements INotifyPropertyChanged, the ItemsSource for the listview is refreshed, the new items are bound, and the existing selection is lost. Without MVVM I would likely have something like this:
VB.NET:
Private Sub lvItems_SelectionChanged(sender As Object, e As SelectionChangedEventArgs)
_selectedSample = lvItems.SelectedItem
If _selectedSample IsNot Nothing Then
_lastSelectedMachine = _selectedSample.MachineName
Else
_lastSelectedMachine = ""
End If
End Sub
And then I would RemoveHandler and AddHandler before and after assigning to the ItemsSource. I cannot see how I can do this while respecting the MVVM pattern however. I have seen some examples online, that suggest using an attached behavior and whatnot. Isn't there a simple and easy way to handle this without having to go dig through dependency properties?
Thank you.