Come eseguire l'override/modificare la proprietà Content di Frame per accettare più visualizzazioni in Xamarin.Forms?

Come eseguire l'override/modificare la proprietà Content di Frame per accettare più visualizzazioni in Xamarin.Forms?

Se ho ragione, potresti ottenerlo impostando il ContentProperty attribuire al tuo PopupFrame class a una proprietà che è essa stessa una raccolta. Questo sovrascriverebbe il ContentProperty di Frame che è Content per permetterti di impostare più viste come contenuto invece di una sola che è l'impostazione predefinita per Frame...

Quindi, se tutto questo ti suona bene, continua a leggere.

Come fare per

Potresti definire un ContentProperty per il tuo PopupFrame classe, in questo modo:

[Xamarin.Forms.ContentProperty("Contents")]
class PopupFrame : Frame
{
    StackLayout contentStack { get; } = new StackLayout();

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


    public PopupFrame()
    {
        Content = contentStack;

        HasShadow = true;
        HorizontalOptions = LayoutOptions.FillAndExpand;
        Padding = 0;
        VerticalOptions = LayoutOptions.Center;
    }
}

Allora sei in grado di fare qualcosa come quello che vuoi:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage 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">

    <StackLayout>
        <t:PopupFrame>
            <t:PopupHeader Text="Test header"/>
            <Label Text="Test content"/>
        </t:PopupFrame>
    </StackLayout>

</ContentPage>

Che dalla mia parte funziona mostrando sia il PopupHeader e il Label :

E infine un po' di teoria su ContentProperty

Quanto segue è tratto letteralmente dal libro del cap. Petzold su Xamarin.Forms.

Ogni classe utilizzata in XAML è consentito definire una proprietà come proprietà del contenuto (a volte chiamata anche proprietà predefinita della classe). Per questa proprietà del contenuto, i tag dell'elemento proprietà non sono obbligatori e qualsiasi contenuto XML all'interno dei tag di inizio e di fine viene assegnato automaticamente a questa proprietà. Molto convenientemente, la proprietà del contenuto di ContentPage è Content , la proprietà del contenuto di StackLayout è Children e la proprietà content di Frame è Content .

Queste proprietà del contenuto sono documentate, ma è necessario sapere dove cercare. Una classe specifica la relativa proprietà del contenuto usando ContentPropertyAttribute. Se questo attributo è allegato a una classe, viene visualizzato nella documentazione dell'API Xamarin.Forms online insieme alla dichiarazione di classe. Ecco come appare nella documentazione per ContentPage :

[Xamarin.Forms.ContentProperty("Content")]
public class ContentPage : TemplatedPage

Se lo dici ad alta voce, suona un po' ridondante:"La proprietà Content è la proprietà content di ContentPage."

La dichiarazione per il Frame la classe è simile:

[Xamarin.Forms.ContentProperty("Content")]
public class Frame : ContentView

StackLayout non ha un ContentProperty attributo applicato, ma StackLayout deriva da Layout<View> e Layout<T> ha un ContentProperty attributo:

[Xamarin.Forms.ContentProperty("Children")]
public abstract class Layout<T> : Layout, IViewContainer<T>
where T : View

Il ContentProperty viene ereditato dalle classi che derivano da Layout<T> , quindi Children è la proprietà del contenuto di StackLayout .


PopupFrame.cs

public class PopupFrame : Frame
{
    StackLayout PopupContent;
    public IList<View> Body
    {
        get => PopupContent.Children;
    }
    public PopupFrame()
    {

        PopupContent = new StackLayout();

        SetDynamicResource(Frame.BackgroundColorProperty, "PopUpBackgroundColor");
        SetDynamicResource(Frame.CornerRadiusProperty, "PopupCornerRadius");
        HasShadow = true;
        HorizontalOptions = LayoutOptions.FillAndExpand;
        Padding = 0;
        VerticalOptions = LayoutOptions.Center;

        Content = PopupContent;
    }

Ora puoi utilizzare

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage 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">

    <StackLayout>
       <t:PopupFrame>
         <t:PopupFrame.Body>
             <t:PopupHeader Text="Test header"/>
             <Label Text="Test content"/>
           </t:PopupFrame.Body>
        </t:PopupFrame>
    </StackLayout>

</ContentPage>