1
votes

I'm new to Xamarin.Forms and Xaml and this. I have made a custom control i would like to utilize as a custom background throughout my app. The custom control is made as a contentview and looks like this.

 <ContentView.Content>
    <ScrollView>
        <StackLayout>
            <RelativeLayout Padding="0" BackgroundColor="Teal" VerticalOptions="Start">
                <Image Source="TopBG" BackgroundColor="Purple" Aspect="Fill" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.6}" />
            </RelativeLayout>
            <Frame Padding="0" Margin="0,-25,0,0" CornerRadius="25" BackgroundColor="{StaticResource Key=Charcoal}">
                <StackLayout Margin="0,0,0,0" VerticalOptions="StartAndExpand" BackgroundColor="Transparent" x:Name="InnerStack">


                    <!--I can insert custom controls here, but htat would determine this custom contentView for one purpose only-->

                </StackLayout>
            </Frame>
        </StackLayout>
    </ScrollView>
</ContentView.Content>

The custom control is then implemented on my ContentPage as such:

<ContentPage.Content>

    <CustomLayouts:ContentBackground>

        <!-- I would instead like to be able to add content here, and have it go into the stacklayout of the custom view.
        This way i could utilize the same background but have different content go into it depending on my wishes -->

    </CustomLayouts:ContentBackground>

</ContentPage.Content>

If i add a label inside that later example it just overrides everything and places a label, but not as intended inside the designated inner stackview of my ContentBackground.

The only thing i can think of is figuring some way of accesing the InnerStackView of my custom contentBackground, then accesing the children property of that Stacklayout and then Children.add(View) to that stack layout. Allthough this means i will have to do it from code and i would like to achieve this behaviour in XAML since that is more familiar to me.

Is this the only way or is there an alternative to achieve my goal in XAML?

2

2 Answers

2
votes

Try use ContentProperty.Simple example:

 [ContentProperty("AddContent")]
 public class YourView: ContentView
 {
    protected ContentView ContentContainer;

    public View AddContent
    {
        get => ContentContainer.Content;
        set => ContentContainer.Content = value;
    } 
    ......
 }

 //in xaml
 <YourView>
   <Label Text="Hello world"/>
 </YourView>
0
votes

In case someone still trying this, you can use ControlTemplate to have a view on multiple pages or app wide,

<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SimpleTheme.App">
    <Application.Resources>
        <ResourceDictionary>
            <ControlTemplate x:Key="TealTemplate">
                <Grid>
                    ...
                    <BoxView ... />
                    <Label Text="Control Template Demo App"
                           TextColor="White"
                           VerticalOptions="Center" ... />
                    <ContentPresenter ... />
                    <BoxView Color="Teal" ... />
                    <Label Text="(c) Xamarin 2016"
                           TextColor="White"
                           VerticalOptions="Center" ... />
                </Grid>
            </ControlTemplate>
            <ControlTemplate x:Key="AquaTemplate">
                ...
            </ControlTemplate>
        </ResourceDictionary>
    </Application.Resources>
</Application>

The magic here is the ContentPresenter, you can place anything inside it will appear just fine. Then to use the desired template, set it for your ContentView.ControlTemplate like so,

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SimpleTheme.HomePage">
    <ContentView x:Name="contentView" Padding="0,20,0,0"
                 ControlTemplate="{StaticResource TealTemplate}">
        <StackLayout VerticalOptions="CenterAndExpand">
            <Label Text="Welcome to the app!" HorizontalOptions="Center" />
            <Button Text="Change Theme" Clicked="OnButtonClicked" />
        </StackLayout>
    </ContentView>
</ContentPage>

Checkout the official docs here.

If you want to create a custom control/layout that you can insert on any page, then you can create your own ContentView with ContentPresenter that will hold your views children,

<!-- Content -->
<ContentPresenter Content="{Binding SomeContent}"/>

where SomeContent can be a BindableProperty of type View.

You can also see an example of custom layouts here.