Wie überschreibe/ändere ich die Content-Eigenschaft von Frame, um mehrere Ansichten in Xamarin.Forms zu akzeptieren?

Wie überschreibe/ändere ich die Content-Eigenschaft von Frame, um mehrere Ansichten in Xamarin.Forms zu akzeptieren?

Wenn ich richtig liege, könnten Sie dies erreichen, indem Sie den ContentProperty setzen Attribut zu Ihrem PopupFrame Klasse zu einer Eigenschaft, die selbst eine Sammlung ist. Dies würde den ContentProperty überschreiben von Frame das ist Content damit Sie mehrere Ansichten als Inhalt festlegen können, anstatt nur einer, was die Standardeinstellung für Frame...

ist

Also, wenn sich das alles gut für Sie anhört, lesen Sie weiter.

Das HowTo

Sie könnten einen ContentProperty definieren für Ihre PopupFrame Klasse, etwa so:

[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;
    }
}

Dann sind Sie in der Lage, so etwas wie das zu tun, was Sie wollen:

<?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>

Was auf meiner Seite funktioniert und sowohl den PopupHeader anzeigt und die Label :

Und zum Schluss noch ein bisschen Theorie zu ContentProperty

Das Folgende ist wörtlich aus dem Buch Ch. Petzold auf Xamarin.Forms.

Jede in XAML verwendete Klasse darf eine Eigenschaft als Inhaltseigenschaft definieren (manchmal auch als Standardeigenschaft der Klasse bezeichnet). Für diese Inhaltseigenschaft sind die Property-Element-Tags nicht erforderlich, und alle XML-Inhalte innerhalb der Start- und End-Tags werden dieser Eigenschaft automatisch zugewiesen. Sehr bequem, die Inhaltseigenschaft von ContentPage ist Content , die Inhaltseigenschaft von StackLayout ist Children , und die Inhaltseigenschaft von Frame ist Content .

Diese Inhaltseigenschaften sind dokumentiert, aber Sie müssen wissen, wo Sie suchen müssen. Eine Klasse gibt ihre Inhaltseigenschaft mithilfe von ContentPropertyAttribute an. Wenn dieses Attribut an eine Klasse angefügt ist, wird es zusammen mit der Klassendeklaration in der Xamarin.Forms-API-Onlinedokumentation angezeigt. So sieht es in der Dokumentation für ContentPage aus :

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

Wenn Sie es laut aussprechen, klingt es etwas überflüssig:"Die Content-Eigenschaft ist die Inhaltseigenschaft von ContentPage."

Die Deklaration für Frame Klasse ist ähnlich:

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

StackLayout hat keinen ContentProperty Attribut angewendet, aber StackLayout leitet sich von Layout<View> ab , und Layout<T> hat einen ContentProperty Attribut:

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

Der ContentProperty -Attribut wird von den Klassen geerbt, die von Layout<T> abgeleitet sind , also Children ist die Inhaltseigenschaft von 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;
    }

Jetzt können Sie verwenden

<?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>