As others have mentioned, it's hard to help precisely when we don't have context. Distilling your problem to a minimal code representation would be extremely helpful. For example, Rushi Soni's answer will work if your controls are bound to individual properties on a class, but there is another answer if you've bound your TextBlock
s directly to your ObservableCollection
:
By default, non-list controls like TextBlock
which are bound to a collection will display the "current" item in the list. WPF maintains a (somewhat magical) view of the collection that keeps track of the current item. You can access the collection view by calling CollectionViewSource.GetDefaultView(ObservableCollection)
and manipulate the current item by using methods MoveCurrentToPrevious
, MoveCurrentToNext
, IsCurrentBeforeFirst
, and IsCurrentAfterLast
on the returned ICollectionView
interface.
Full code for this scenario:
XAML:
<UserControl.Resources>
<!-- the MyCollection type is derived from ObservableCollection<MyItem> -->
<my:MyCollection x:Key="myCollection">
<my:MyItem Text="One" Anzhal="1"/>
<my:MyItem Text="Two" Anzhal="2"/>
<my:MyItem Text="Three" Anzhal="3"/>
</my:MyCollection>
</UserControl.Resources>
<!-- data context of the top level control is the observable collection defined here in XAML, but
could also be created and assigned in code -->
<DockPanel Name="grid1" DataContext="{StaticResource myCollection}" >
<!-- navigation controls -->
<Grid DockPanel.Dock="Top" >
<Button HorizontalAlignment="Left" Content="< Previous" Name="buttonPrev" Click="buttonPrev_Click" />
<Button HorizontalAlignment="Right" Content="Next >" Name="buttonNext" Click="buttonNext_Click" />
</Grid>
<!-- display of the current item -->
<TextBlock Padding="5" DockPanel.Dock="Top" Text="{Binding Text}" />
<TextBlock Padding="5" DockPanel.Dock="Top" Text="{Binding Anzhal}" />
<!-- list display of all items (not necessary but helpful for visualizing the behavior) -->
<ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="Text" />
</DockPanel>
Class definitions for the collection and the contained items:
public class MyCollection : ObservableCollection<MyItem> { }
public class MyItem
{
// NOTE: these must be get/set properties in order for binding to work
public string Text { get; set; }
public int Anzhal { get; set; }
}
And the code for handling the Next/Previous button clicks, which demonstrates wrapping around when reaching the ends of the collection:
ICollectionView GetView()
{
// use FindResource() to retrieve the collection since it is defined in XAML
// Then we retrieve WPF's view into the collection so we can manipulate the
// current item (next, previous)
return CollectionViewSource.GetDefaultView(FindResource("myCollection"));
}
private void buttonNext_Click(object sender, RoutedEventArgs e)
{
var view = GetView();
// wrap around behavior
view.MoveCurrentToNext();
if (view.IsCurrentAfterLast) {
view.MoveCurrentToFirst();
}
}
private void buttonPrev_Click(object sender, RoutedEventArgs e)
{
var view = GetView();
// wrap around behavior
view.MoveCurrentToPrevious();
if (view.IsCurrentBeforeFirst) {
view.MoveCurrentToLast();
}
}
Hope that helps.