【问题标题】:Custom layout, Xamarin forms. Best approach自定义布局,Xamarin 表单。最佳方法
【发布时间】:2018-07-06 14:47:23
【问题描述】:

我是 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 中目标的唯一方法还是有替代方法?

【问题讨论】:

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


【解决方案1】:

尝试使用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>

【讨论】:

    【解决方案2】:

    如果有人仍在尝试此操作,您可以使用 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

    如果您想创建一个可以在任何页面上插入的自定义控件/布局,那么您可以使用ContentPresenter 创建您自己的ContentView 来保存您的子视图,

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

    其中SomeContent 可以是BindableProperty 类型的View

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

    【讨论】:

      猜你喜欢
      • 2021-08-04
      • 1970-01-01
      • 1970-01-01
      • 2016-08-12
      • 1970-01-01
      • 2022-06-13
      • 1970-01-01
      • 2012-10-27
      • 1970-01-01
      相关资源
      最近更新 更多