xamarinxamarin.formsdata-bindingxamarin.android

Setting BindingContext for ContentView inside CarouselView block CurrentItemChanged event handler from working


I have a CarouselView with 3 ContentViews inside:

 <CarouselView x:Name="CarouselObject"
                      Grid.RowSpan="2"
                      ItemsSource="{Binding Views}"
                      ItemTemplate="{StaticResource mySelector}" 
                      CurrentItemChanged="CarouselView_CurrentItemChanged"
                      Loop="False"/>

My ViewModel:

internal class CVVM
{
    public ObservableCollection<View> Views { get; set; }
    public CVVM()
    {
        Views = new ObservableCollection<View>()
        {
            new testpage2(),
            new testpage1(),
            new ReleaseRadarView()
        };
    }
}

I want my app to do something when I slide between the ContentViews so I tried using the CurrentItemChanged event handler. The problem is that one of my ContentViews has it's bindingcontext run at runtime and I think, because of that, the event handler doesn't fire at all for this ContentView only. The ContentView XAML code:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:vm="clr-namespace:Planetarium_V2.Classes"
         x:Class="Planetarium_V2.testpage2">
<ContentView.BindingContext>
    <vm:GameCardPack />
</ContentView.BindingContext>
<ContentView.Content>
    <Grid RowSpacing="0"
      BackgroundColor="#2d2d2d">
        <Grid.RowDefinitions>
            <RowDefinition Height="200" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <CollectionView Grid.Row="1"
                    ItemsSource="{Binding cards}"
                    SelectionMode="Single"
                    SelectionChanged="CollectionView_SelectionChanged"
                        x:Name="CollectionViewInstance">

The ContentView:

public partial class testpage2 : ContentView
{
    public testpage2 ()
    {
        InitializeComponent ();
        CreateBindingContextAsync();
    }
    private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var ItemSelected = e.CurrentSelection[0] as GameCard;
        var newPage = new GameDetailPage();
        newPage.BindingContext = ItemSelected;
        Navigation.PushAsync(newPage);
    }
    private async void CreateBindingContextAsync()
    {
        try
        {
            GameCardPack pack = await new JSONUnpacker().Unpack();
            this.BindingContext = pack;
        }
        catch (Exception e)
        {

            Console.WriteLine(e.Message);
        }
    }
}

}

I tried using implementing OnPropertyChanged() but it didn't really do anything.

The VisualModel for the ContentView:

    public class GameCardPack : BaseViewModel
{
    ObservableCollection<GameCard> _cards { get; set; }
    public ObservableCollection<GameCard> cards
    {
        get
        {
            return _cards;
        }
        set
        {
            _cards = value;
            OnPropertyChanged(nameof(cards));
        }
    }
    public GameCardPack()
    {
        cards = new ObservableCollection<GameCard>();
    }
    public void AddCard(GameCard card)
    {
        card.ConvertToUri();
        cards.Add(card);
    }
}

Edit: Here's the GameCard class:

 public class GameCard
{
    public string Title { get; set; }
    public string[] tagsList { get; set; }

    public string[] imageURLS { get; set; }
    public Uri[] imageURIS { get; set; }
    public string originalPrice { get; set; }
    public string newPrice { get; set; }
    public string description { get; set; }
    public GameCard()
    {
        Title = "PlaceholderTitle";
        tagsList = new string[]
        {
            "tag1",
            "tag2",
            "tag3"
        };
        imageURLS = new string[]
        {
            "Placeholder_view_vector.png",
            "Placeholder_view_vector.png",
            "Placeholder_view_vector.png",
            "Placeholder_view_vector.png",
            "Placeholder_view_vector.png"
        };
        originalPrice = "13.57";
        newPrice = "4.20";
        description= string.Empty;
    }
    public void ConvertToUri()
    {
         Uri[] auximageURIs = new Uri[]
            {
                new Uri(imageURLS[0]),
                new Uri(imageURLS[1]),
                new Uri(imageURLS[2]),
                new Uri(imageURLS[3]),
                new Uri(imageURLS[4])
            };
        imageURIS= auximageURIs;
    }
    
}

The testpage1 and ReleaseRadarView contentViews are just some empty ContentViews currently. I plan on building them too but I want to figure out this problem for now.


Solution

  • I solved this problem by instead of setting the binding context for the ContentView I set it for the CollectionView

    public async void CreateBindingContextAsync()
        {
            try
            {
                GameCardPack pack = await new JSONUnpacker().Unpack();
                CollectionViewInstance.BindingContext= pack;
            }
            catch (Exception e)
            {
    
                Console.WriteLine(e.Message);
            }
        }