简体   繁体   中英

How do I create a Xamarin Page that can host other Pages?

I'd like to write a Xamarin Page class that mimics the Pivot control which is used by TabbedPage on Windows Phone, but which is unavailable on Windows Desktop. So I'd like to have it host several child Page s, only one of which will be visible at a time, as well as a control of its own which will allow the user to switch between the children. How would I go about this?

You're looking CarouselView exactly. It uses FlipView on WinRT and UWP platforms.

You can find more information from Xamarin blog and Xamarinhelp.com . They also have pre-release nuget package.

I think you'll have to write that on your own. Use CarouselView , add it to Grid or AbsoluteLayout or RelativeLayout (I mean, put it on background so you'll be able to add carousel of titles on top of it. Or you might not wanna do that, in which case you'll just use vertical stack layout). You'll also need to add custom control for navigation and synchronize changes between page titles carousel and actual pages carousel.

I found this blog post on how to host pages in views. Based on that, I made the following view class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;

namespace SGB
{
    public class PageView : View
    {
        public PageView()
        {
        }

        public static readonly BindableProperty ContentProperty = BindableProperty.Create<PageView,Page> (s => s.Content, null);

        public Page Content {
            get
            {
                return (Page)GetValue (ContentProperty); 
            }
            set
            { 
                SetValue (ContentProperty, value);
                LayoutContent();
            }
        }

        protected override void OnSizeAllocated(double width, double height)
        {
            base.OnSizeAllocated(width, height);
            LayoutContent();
        }

        private void LayoutContent()
        {
            if (Content != null)
            {
                Content.Layout(new Rectangle(0, 0, Width, Height));
            }
        }
    }
}

and this renderer class:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

using Xamarin.Forms;
using Xamarin.Forms.Platform.WinRT;

using Page = Xamarin.Forms.Page;

using SGB;

[assembly: ExportRenderer(typeof(PageView), typeof(SGB.Windows.PageViewRenderer))]
namespace SGB.Windows
{
    public class PageViewRenderer : ViewRenderer<PageView, FrameworkElement>
    {
        private Page currentPage;
        private FrameworkElement FrameworkElement;

        public PageViewRenderer()
            : base()
        {
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if ((e.PropertyName == "Content") || (e.PropertyName == "Renderer"))
            {
                SetPage(((PageView)Element).Content);
            }
        }

        private void SetPage(Page page)
        {
            if (page == currentPage)
            {
                return;
            }

            if (currentPage != null)
            {
                ((IPageController)page).SendDisappearing();

                currentPage.Parent = null;
            }

            currentPage = page;

            if (page != null)
            {
                var renderer = page.GetOrCreateRenderer();
                FrameworkElement = renderer.ContainerElement;
                SetNativeControl(FrameworkElement);

                page.Parent = FindPage();

                ((IPageController)page).SendAppearing();
            }
        }

        private Page FindPage()
        {
            for (Element element = Element; element != null; element = element.Parent)
            {
                if (element is Page)
                {
                    return (Page)element;
                }
            }

            return null;
        }
    }
}

Now I have that, I can create a ContentPage containing a PageView , and I have what I want.

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