自定义布局,Xamarin表单。最好的方法

时间:2018-01-27 11:25:47

标签: c# xaml xamarin.forms app.xaml

我是Xamarin.Forms和Xaml的新手。我已经制作了一个自定义控件,我希望在整个应用程序中将其用作自定义背景。自定义控件是内容视图,看起来像这样。

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

然后在我的ContentPage上实现自定义控件:

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

如果我在后面的示例中添加了一个标签,它只是覆盖所有内容并放置一个标签,但不是在我的ContentBackground的指定内部堆栈视图中的预期。

我唯一能想到的是找到一些方法来访问我的自定义contentBackground的InnerStackView,然后访问该Stacklayout的children属性,然后访问Children.add(View)到该堆栈布局。虽然这意味着我将不得不从代码中完成它,我想在XAML中实现这种行为,因为这对我来说更为熟悉。

这是唯一的方式还是有替代方法来实现我在XAML中的目标?

2 个答案:

答案 0 :(得分:2)

尝试使用ContentProperty。简单示例:

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

答案 1 :(得分:0)

如果有人仍在尝试此操作,您可以使用ControlTemplate在多个页面或应用范围内查看视图,

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

这里的魔力是ContentPresenter,你可以在里面放任何东西就会很好。然后,要使用所需的模板,请将其设置为ContentView.ControlTemplate,如此,

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

查看官方文档here

如果您想要创建可以在任何页面上插入的自定义控件/布局,那么您可以使用ContentView创建自己的ContentPresenter来保存您的观看次数,

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

其中SomeContent可以是BindableProperty类型的View

您还可以查看自定义布局here的示例。