silverlight listbox autoscroll behavior
July 29, 2011 at 2:09 AM
—
dsoltesz
Sometimes your list boxes can have a lot of items in them. Even though you may order the list it still can be difficult for the user to find and item. I like to give the user the abiltiy to search for an item in the listbox. To keep this clean with MVVM, I created a behavior that can autoscroll for your via databinding.
Here is the behavior
/// <summary>
/// Auto scroll listbox to item that is bound to the FoundItem property
/// </summary>
public class ListBoxItemAutoScrollBehavior : Behavior<ListBox>
{
#region Properties
/// <summary>
/// Item that is bound to listbox that you want to autoscroll to
/// </summary>
public object FoundItem
{
get { return GetValue(FoundItemProperty); }
set { SetValue(FoundItemProperty, value); }
}
public static readonly DependencyProperty FoundItemProperty = DependencyProperty.Register("FoundItem", typeof(object), typeof(ListBoxItemAutoScrollBehavior), new PropertyMetadata(FoundItemChanged));
private static void FoundItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ListBoxItemAutoScrollBehavior)d).AssociatedObject.ScrollIntoView(e.NewValue);
}
#endregion
}
Make sure you add a reference to System.Windows.Interactivity.
To use the behavior I do something like this.
<ListBox ItemsSource="{Binding MyItems}" DisplayMemberPath="ItemName" SelectionMode="Multiple">
<i:Interaction.Behaviors>
<behaviors:ListBoxItemAutoScrollBehavior FoundItem="{Binding FoundItem}"/>
</i:Interaction.Behaviors>
</ListBox>
<TextBox Text="{Binding ItemToFind, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" BorderThickness="1" />
Now in your view model just define your properties to bind to.
public ObservableCollection<Item> MyItems
{
get { return _myItems; }
set
{
if (_myItems == value) return;
_myItems = value;
OnPropertyChanged(() => MyItems);
}
}
public string ItemToFind
{
get { return _itemToFind; }
set
{
if (_itemToFind == value) return;
_itemToFind = value;
FoundItem = MyItems.FirstOrDefault(o => o.ItemName.StartsWith(_itemToFind, StringComparison.CurrentCultureIgnoreCase));
OnPropertyChanged(() => ItemToFind);
OnPropertyChanged(() => FoundItem);
}
}
public Item FoundItem { get; set; }
Now when the user types in something into the textbox, it will autoscroll to the item that is found