简体   繁体   中英

How to acces object inside CarouselView Xamarin.Forms

I have a Xamarin.Forms app that displays a ViewFlipper ( https://github.com/TorbenK/ViewFlipper ) inside a CarouselView.

I would like the ViewFlipper to flip back to the front when changing pages inside the carousel. But I can't seem to figure out how to access the ViewFlipper.

I have the following working code:

public class CarouselContent
{
    public string FrontImg { get; set; }
    public string BackImg { get; set; }
}

public class MainPage : ContentPage
{
    public MainPage()
    {
        var pages = new ObservableCollection<CarouselContent>();

        var page1 = new CarouselContent();
        page1.FrontImg = "page1Front";
        page1.BackImg = "page1Back";

        var page2 = new CarouselContent();
        page2.FrontImg = "page2Front";
        page2.BackImg = "page2Back";

        pages.Add(page1);
        pages.Add(page2);

        var carouselView = new Carousel(pages);

        Content = carouselView;
    }
}

public class Carousel : AbsoluteLayout
{
    private DotButtonsLayout dotLayout;
    private CarouselView carousel;

    public Carousel(ObservableCollection<CarouselContent> pages)
    {
        carousel = new CarouselView();

        var template = new DataTemplate(() =>
        {
            //create page
            var absLayout = new AbsoluteLayout();

            //create images for the flipper
            var frontImg = new Image
            {
                Aspect = Aspect.AspectFit
            };
            frontImg.SetBinding(Image.SourceProperty, "FrontImg");

            var backImg = new Image
            {
                Aspect = Aspect.AspectFit
            };
            backImg.SetBinding(Image.SourceProperty, "BackImg");

            //create flipper
            var flipper = new ViewFlipper.FormsPlugin.Abstractions.ViewFlipper();
            flipper.FrontView = frontImg;
            flipper.BackView = backImg;              

            //Add flipper to page
            absLayout.Children.Add(flipper);

            return absLayout;
        });

        carousel.ItemsSource = pages;
        carousel.ItemTemplate = template;

        Children.Add(carousel);
    }
}

I tried adding the ViewFlipper to the CarouselContent but I couldn't get that to work. Any ideas?

EDIT:

I tried creating an AbsoluteLayout with bindable items and bind the items created in CarouselContent in the datatemplate of the CarouselView, but the line '(b as BindableAbsLayout).Children.Add((View)v);' in BindableAbsLayout is never called. What am I doing wrong?

class BindableAbsLayout : AbsoluteLayout
{
    public static readonly BindableProperty ItemsProperty =
        BindableProperty.Create(nameof(Items), typeof(ObservableCollection<View>), typeof(BindableAbsLayout), null,
            propertyChanged: (b, o, n) =>
            {
                (n as ObservableCollection<View>).CollectionChanged += (coll, arg) =>
                {
                    switch (arg.Action)
                    {
                        case NotifyCollectionChangedAction.Add:
                            foreach (var v in arg.NewItems)
                                (b as BindableAbsLayout).Children.Add((View)v);
                            break;
                        case NotifyCollectionChangedAction.Remove:
                            foreach (var v in arg.NewItems)
                                (b as BindableAbsLayout).Children.Remove((View)v);
                            break;
                    }
                };
            });

    public ObservableCollection<View> Items
    {
        get { return (ObservableCollection<View>)GetValue(ItemsProperty); }
        set { SetValue(ItemsProperty, value); }
    }
}


public class CarouselContent
{
    private ViewFlipper.FormsPlugin.Abstractions.ViewFlipper _flipper;
    private ObservableCollection<View> _items;

    public ObservableCollection<View> Items
    {
        get { return _items; }
    }

    public CarouselContent(string frontImgStr, string backImgStr)
    {
        _items = new ObservableCollection<View>();

        _flipper = new ViewFlipper.FormsPlugin.Abstractions.ViewFlipper();

        var frontImg = new Image
        {
            Aspect = Aspect.AspectFit
        };
        frontImg.Source = frontImgStr;

        var backImg = new Image
        {
            Aspect = Aspect.AspectFit
        };
        backImg.Source = backImgStr;

        _flipper.FrontView = frontImg;
        _flipper.BackView = backImg;

        AbsoluteLayout.SetLayoutBounds(_flipper, new Rectangle(0.5, 0.05, 0.85, 0.85));
        AbsoluteLayout.SetLayoutFlags(_flipper, AbsoluteLayoutFlags.All);

        Items.Add(_flipper);
    }
}


public class Carousel : AbsoluteLayout
{
    private DotButtonsLayout dotLayout;
    private CarouselView carousel;

    public Carousel(ObservableCollection<CarouselContent> pages)
    {
        carousel = new CarouselView();

            var template = new DataTemplate(() =>
            {
                var absLayout = new BindableAbsLayout();
                absLayout.BackgroundColor = Color.FromHex("#68BDE4");
                absLayout.SetBinding(BindableAbsLayout.ItemsProperty,"Items");
                return absLayout;
            });

        carousel.ItemsSource = pages;
        carousel.ItemTemplate = template;

        Children.Add(carousel);
    }
}

Not sure what the best practice is here, but you could try accessing it via the ItemSelected Event (which fires every time you change back and forth in the carouselview)

Wire it up

carousel.ItemSelected += carouselOnItemSelected;

Get your ViewFlipper

private void carouselOnItemSelected(object sender, SelectedItemChangedEventArgs selectedItemChangedEventArgs)
        {
            CarouselContent carouselContent = selectedItemChangedEventArgs.SelectedItem;
            ViewFlipper viewFlipper = carouselContent.Children[0];
            viewFlipper.FlipState = ViewFlipper.FrontView;
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM