I have a ListView
with some items, and when I select one of those items, I am moved to a new page with a Horizontal CollectionView
, with my SelectedItem
as the item I selected on the page before. I have this part working.
My problem is, if the item I selected on the page before is too far to the right, (having to scroll to reach it) then my SelectedItem
won't automatically show on screen.
Image with visible selected item:
Image where selected item is not visible:
As you can see, when I selected the item "cat 7" it is not visible on the page.
My desired result is that, once an item is selected from the page before, it will always be visible immediately on the following page.
Does anybody know a way in which I can achieve this result?
My xaml:
<CollectionView ItemsSource="{Binding CategorieList}"
ItemsLayout="HorizontalList"
x:Name="CategoryList"
VerticalOptions="Start"
Margin="0,22,0,0"
HeightRequest="32"
SelectionMode="Single"
SelectedItem="{Binding CategorieListSelectedItem, Mode=TwoWay}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal" />
<VisualState Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="transparent" />
<Setter TargetName="SelectedLabel" Property="Label.TextColor" Value="#004EFF"/>
<Setter TargetName="SelectedLabel" Property="Label.FontSize" Value="22"/>
<Setter TargetName="SelectedLabel" Property="Label.Margin" Value="20,-2,20,0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Label Text="{Binding Name}"
x:Name="SelectedLabel"
Margin="20,0,20,0"
TextColor="#707070"
FontSize="20"
FontFamily="{StaticResource Helvetica}"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
My ViewModel:
public Categories CategorieListSelectedItem
{
get
{
return categorieListSelectedItem;
}
set
{
categorieListSelectedItem = value;
OnPropertyChanged("CategorieListSelectedItem");
ProductList.Clear();
if(categorieListSelectedItem.Products != null)
{
foreach (var item in CategorieListSelectedItem.Products)
{
productList.Add(new ProductDetailsViewModel(item));
}
}
OnPropertyChanged("ProductList");
}
}
I am not sure how many Name
in your CategorieList
. I use 8 for example. When the count is not enough, the Name
would show but not in the center.
public partial class Page3 : ContentPage
{
public ObservableCollection<Categories> CategorieList { get; set; }
public Categories SelectedCategorie { get; set; }
public Page3()
{
InitializeComponent();
CategorieList = new ObservableCollection<Categories>()
{
new Categories(){ Name="cat 1"},
new Categories(){ Name="cat 2"},
new Categories(){ Name="cat 3"},
new Categories(){ Name="cat 4"},
new Categories(){ Name="cat 5"},
new Categories(){ Name="cat 6"},
new Categories(){ Name="cat 7"},
new Categories(){ Name="cat 8"},
//new Categories(){ Name="cat 9"},
//new Categories(){ Name="cat 10"},
//new Categories(){ Name="cat 11"},
};
SelectedCategorie = CategorieList.Skip(6).FirstOrDefault();
this.BindingContext = this;
}
protected override void OnAppearing()
{
CategoryList.ScrollTo(CategoryList.SelectedItem, null, ScrollToPosition.Center, false);
}
}
public class Categories
{
public string Name { get; set; }
}
SelectedItem is cat4
:
CategorieListSelectedItem = CategorieList.Skip(3).FirstOrDefault();
SelectedItem is cat7
:
CategorieListSelectedItem = CategorieList.Skip(6).FirstOrDefault();