Reputation: 995
I have a ListBox of Items and a Search TextBox and Search Button, i want to enter the search text in the TextBox and Click Search Button so the ListBox highlight that item and get it on screen (for lengthy list). Is it possible to do this using ICollectionView? and if not possible how to implement this scenario. Note: after googling i found all samples talking about Filtering but i need searching. Thanks for bearing with us.
Upvotes: 0
Views: 1235
Reputation: 1919
You can achieve this by implementing a Prism Behavior:
public class AutoScrollingBehavior:Behavior<ListBox>
{
protected override void OnAttached()
{
base.OnAttached();
var itemsSource = AssociatedObject.ItemsSource as ICollectionView;
if (itemsSource == null)
return;
itemsSource.CurrentChanged += ItemsSourceCurrentChanged;
}
void ItemsSourceCurrentChanged(object sender, EventArgs e)
{
AssociatedObject.ScrollIntoView(((ICollectionView)sender).CurrentItem);
AssociatedObject.Focus();
}
}
Another approach is listening to ListBox.SelectionChanged instead of ICollectionView.CurrentChanged.
public class AutoScrollingBehavior:Behavior<ListBox>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SelectionChanged += AssociatedObjectSelectionChanged;
}
void AssociatedObjectSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count <= 0)
return;
AssociatedObject.ScrollIntoView(e.AddedItems[0]);
AssociatedObject.Focus();
}
}
On Xaml:
<ScrollViewer Height="200">
<ListBox x:Name="listbox" ItemsSource="{Binding Path=NamesView}" SelectionMode="Single"
IsSynchronizedWithCurrentItem="True">
<i:Interaction.Behaviors>
<local:AutoScrollingBehavior/>
</i:Interaction.Behaviors>
</ListBox>
</ScrollViewer>
Inside searching command, you set NamesView.MoveCurrentTo(foundItem)
. However this approach will only scroll to the edge, instead of center, might you expected. If you want it to scroll to the center, you might need ItemContainerGenerator
.
In your view model who holds the ICollectionView:
private string _searchText;
public string SearchText
{
get { return _searchText; }
set
{
_searchText = value;
RaisePropertyChanged("SearchText");
}
}
private ICommand _searchCommand;
public ICommand SearchCommand
{
get { return _searchCommand ?? (_searchCommand = new DelegateCommand(Search)); }
}
private void Search()
{
var item = _names.FirstOrDefault(name => name == SearchText);
if (item == null) return;
NamesView.MoveCurrentTo(item);
}
On Xaml, bind TextBox.Text to SearchText and bind search button's Command to SearchCommand.
Hope it can help.
Upvotes: 0