How can I combine XAML and a template into one C# template with Rg.Plugins.Popup?

157 views Asked by At

I would like to simplify the addition of dialog popups in my code to the absolute minimum needed.

Currently I have this code:

<pages:PopupPage
    x:Class="Test.Popup"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup">
    <ContentView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <t:PopupFrame>
           <Label Text="ABC" />
           <Label Text="ABC" />
        </t:PopupFrame>
    </ContentView>
</pages:PopupPage>
public partial class Popup : Rg.Plugins.Popup.Pages.PopupPage
{
    public Popup()
    {
        InitializeComponent();
    }
}

And I have PopupFrame here:

[Xamarin.Forms.ContentProperty("Contents")]
public class PopupFrame : Frame
{
    StackLayout contentStack { get; } = new StackLayout()
    {
        Spacing = 0,
        Padding = new Thickness(0),
        Orientation = StackOrientation.Vertical
    };
    public IList<View> Contents { get => contentStack.Children; }

    public PopupFrame()
    {
        Content = contentStack;
        HasShadow = true;
        HorizontalOptions = LayoutOptions.FillAndExpand;
        Padding = 0;
        SetDynamicResource(BackgroundColorProperty, "PopUpBackgroundColor");
        SetDynamicResource(CornerRadiusProperty, "PopupCornerRadius");
        VerticalOptions = LayoutOptions.Center;   
    }
}

Can anyone suggest a way that I can combine these two so that only the following would be required:

<t:PopupPage
    x:Class="Test.Popup"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:t="clr-namespace:Test.Templates">
    <Label Text="ABC" />
    <Label Text="ABC" />
</pages:PopupPage>

So what I am looking for is content for this:

[Xamarin.Forms.ContentProperty("Contents")]
public class Popup : Rg.Plugins.Popup.Pages.PopupPage 
{
}

Update: Here's what I have tried based on the suggested answer:

<?xml version="1.0" encoding="UTF-8" ?>
<pages:PopupPage
    x:Class="Memorise.DecksTab.CopyDeckPopup"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup">
    <Label Text="ABC" />
    <Label Text="ABC" />
</pages:PopupPage>

With backing code:

[Xamarin.Forms.ContentProperty("Contents")]
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CopyDeckPopup : Rg.Plugins.Popup.Pages.PopupPage
{

    PopupFrame contentFrame { get; } = new PopupFrame();

    public IList<View> Contents { get => contentFrame.Contents; }

    public CopyDeckPopup(string clickedDeckName, string clickedDeckDescription)
    {
        BindingContext = new CopyDeckPopupViewModel(clickedDeckName, clickedDeckDescription);
        InitializeComponent();
        Content = new ContentView()
        {
            HorizontalOptions = LayoutOptions.FillAndExpand,
            VerticalOptions = LayoutOptions.FillAndExpand,
            Content = contentFrame
        };
    }

}

It's giving me this error BUT the display is correct and I see two ABCs.

enter image description here

1

There are 1 answers

0
deczaloth On BEST ANSWER

From this piece of code:

<pages:PopupPage
    x:Class="Test.Popup"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup">
    <ContentView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <t:PopupFrame>
           <Label Text="ABC" />
           <Label Text="ABC" />
        </t:PopupFrame>
    </ContentView>
</pages:PopupPage>

it can be seen that the ContentProperty of PopupPage is a single View (which is being occupied by a ContentView in the code above).

But if you want to be able to write code like

<t:PopupPage
    x:Class="Test.Popup"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:t="clr-namespace:Test.Templates">
   <Label Text="ABC" />
   <Label Text="ABC" />
</pages:PopupPage>

then you want PopupPage's ContentProperty to be such that it is capable of taking a list of items (like to two Labels in the code above) and additionally that those items are set to your PopupFrame which should be placed inside a ContentView...

All you have to do is modify PopupPage (which i am assuming inherits from ContentPage[?]) to accept multiple items as its contents, as follows

[Xamarin.Forms.ContentProperty("Contents")]
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PopupPage : ContentPage
{

    PopupFrame contentFrame { get; } = new PopupFrame();

    public IList<View> Contents { get => contentFrame.Contents; }

    public PopupPage()
    {
        InitializeComponent();
        Content = new ContentView()
        {
            HorizontalOptions = LayoutOptions.FillAndExpand,
            VerticalOptions = LayoutOptions.FillAndExpand,
            Content = contentFrame
        };
    }
}

By doing that, now you will be able to write the kind of code you want

<?xml version="1.0" encoding="utf-8" ?>
<t:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:t="clr-namespace:popupframe"
    x:Class="popupframe.MainPage">
    <Label Text="Label1"/>
    <Label Text="Label2"/>
</t:PopupPage>