Question

I'm developing a WPF/MVVM application and I have a listbox binding to data in a ViewModel. At various points I need the view model to cause the listbox to scroll to a given element.

How can I do this without creating a custom control and while still maintaining good separation of concerns?

I've currently got it working by creating a custom behavior class in the view layer with a dependency property VisibleIndex which the XAML code then binds to an integer in the view model:

<ListBox x:Name="myListBox" 
        local:ListBoxVisibilityBehavior.VisibleIndex="{Binding VisibleIndex}">

When the integer is set it triggers the dependency properties update handler which tells the listbox to scroll to the associated index.

This seems a bit hacky though because the dependency property value is never changed by the listbox and the update handler only gets called when the value changes, so the only way to ensure that the relevent item is visible is to do something like this:

// view-model code
this.VisibleIndex = -1;
this.VisibleIndex = 10;

The only reason I'm using a behaviour class at the moment is for binding my custom dependency property, is there a way to do something like this with events instead?

Was it helpful?

Solution 2

For anyone else interested in the answer to this one of the MS engineers on the WPF forum cleared it up for me. Instead of binding to an event directly you bind to a wrapper object that encapsulates that event. The behaviour can then grab the reference to the wrapper from its DP and do whatever it wants with it i.e. subscribe to the event, trigger it etc.

OTHER TIPS

Attached properties are somewhat required in your case - as at some point, 'somewhere' you need to call the following method...

ListBox.ScrollIntoView(item)  

or

ListBoxItem.BringIntoView();

And for that you need some sort of code behind - and attached properties/behaviors are a nice way of packaging that, w/o impacting your MVVM.

Having said that - if you just need to have your 'selected item' scrolled into view at all times (which is the case most of the time). Then you could use a different attached-property based solution (that again):

mvvm how to make a list view auto scroll to a new Item in a list view

All you have to do then is to set or bind to SelectedItem.

That's a bit 'nicer' if you wish - but the mechanism is the same.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top