1

I have a MVVM view where I bind a DataGrid.ItemsSource to an ObservableCollection in the underlying view model. The data is a live log of events that my application pulls from a server. The view model adds log entries to my ObservableCollection as they come in.

I want my DataGrid, assuming it's already scrolled all the way to the bottom, to auto scroll so that the most recently added entry is always visible. Does anyone know how to do this given the MVVM setup?

Nathan A
  • 11,059
  • 4
  • 47
  • 63

1 Answers1

1

Does anyone know how to do this given the MVVM setup?

There are really two simple options here:

  1. Use code behind. While MVVM really does discourage this, there are times when code behind is still appropriate or reasonable. Since this is a 100% pure-view related concern, using code behind (in my opinion) isn't unreasonable.
  2. Create an attached property or Blend-style behavior to add the runtime behavior you want to the View from xaml. This is still, effectively, code behind, but moves it into a reusable form, since the behavior you write can be used on any DataGrid.
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • I was pretty sure I'd end up implementing this in code behind, but I'm not sure what event to tie my "manipulations" to. I can't seem to find an event that is triggered when the underlying data source changes. I don't want to attach to my underlying data source's CollectionChanged event as it takes several bindings already to get to it through my view, and the ObservableCollection itself may change from time to time (such as when the server connection is lost). – Nathan A Jun 26 '13 at 16:18
  • @NathanA Check out the `LoadingRow` event - this should fire any time new rows of data are added, which (I assume) would allow you to handle your scroll as needed. – Reed Copsey Jun 26 '13 at 16:31
  • @ReedCopsey Thanks for the idea. I tried it, but that only works if I turn off EnableRowVirtualization, since LoadingRow is only called when the DataGridRow is loaded. If the grid is virtualizing, the new item won't be visible yet, so the DataGridRow is not created when the new item is added. Not to mention, as you scroll up and down, the event is called for every item that moves into view. So yes, that is a solution if I'm willing to disable EnableRowVirtualization, but as my Log may contains thousands of entries, I'm not sure I want to consider turning that off yet. – Nathan A Jun 26 '13 at 16:42
  • @NathanA With virtualization, I think your only real option is to listen to the `ItemsSource`. You could make a behavior that completely abstracted this (so it wouldn't be tied to your actual data) by listening for changes to the ItemsSouce property of the DataGrid. See: http://stackoverflow.com/a/10709051/65358 – Reed Copsey Jun 26 '13 at 16:50