【问题标题】:Is there a way to set content for StackLayout or Grid from a StaticResource有没有办法从 StaticResource 为 StackLayout 或 Grid 设置内容
【发布时间】:2021-04-01 09:28:25
【问题描述】:

查看我的 XAML,我注意到基本上彼此重复的区域,由于我喜欢保持干净,我在想是否有办法减少 XAML 中的重复代码。

所以我想做的是能够为 StackLayout、Grid、Frame 等控件设置内容。

我创建了一个页面级资源,但我不确定如何使用它。

<ContentPage.Resources>
    <StackLayout x:Key="CommonDetails">
        <Label Text="First Name"/>
        <Label Text="Last Name"/>
    </StackLayout>
</ContentPage.Resources>

<StackLayout>
    <CommonDetails>
    <Label Text="Extra Uncommon Data"/>
</StackLayout>

<StackLayout>
    <CommonDetails>
    <Label Text="Extra Uncommon Data"/>
    <Label Text="Extra Uncommon Data"/>
    <Label Text="Extra Uncommon Data"/>
</StackLayout>

【问题讨论】:

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


    【解决方案1】:

    Resources 中,您可以改为定义ControlTemplete

    <ContentPage.Resources>
        <ControlTemplate x:Key="commonDetails">
            <StackLayout>
                <Label Text="First Name"/>
                <Label Text="Last Name"/>
                <ContentPresenter/>
            </StackLayout>
        </ControlTemplate>
    </ContentPage.Resources>
    

    棘手的部分来了,因为要使用它,您需要ContentView,但在您的情况下,“正常”ContentView 无法完成这项工作,因为他们只接受一个child:您必须创建一个特殊的ContentView,它接受多个视图。

    你可以这样做:

    // Overriding the ContentProperty allows you 
    // to have a ContentView that accepts multiple childs.
    [Xamarin.Forms.ContentProperty("Contents")]
    public class View1 : ContentView
    {
        StackLayout contentStack { get; } = new StackLayout();
        
        public IList<View> Contents { get => contentStack.Children; }
    
        public View1()
        {
            Content = contentStack;
        }
    }
    

    有了它,剩下的就很简单了,因为在任何Page 中,您都可以定义一个自定义ControlTemplate 并将其设置为您的特殊ContentView,如下所示

    <local:View1 ControlTemplate="{StaticResource commonDetails}">
        <Label Text="Occupation1"/>
        <Label Text="Occupation2"/>
    </local:View1>
    

    就是这样,我觉得这很有用!

    【讨论】:

    • 我选择了这个作为答案,因为后面发布的一个与这个非常相似,但是我喜欢这个,因为它解释了如何添加多个视图子项。我很可能只是将它们组合在一个 Grid 或 Stack 视图中,以避免使用这些额外的代码,但很高兴知道这一点以备将来使用。谢谢!
    【解决方案2】:

    解决方案 1:

    您可以使用控件模板。

     <!--  Grid Template -->
        <ControlTemplate x:Key="GridTemplate">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <ContentPresenter Grid.Row="0" />
                <Label
                    Grid.Row="1"
                    BackgroundColor="Accent"
                    Text="Grid Template" />
            </Grid>
        </ControlTemplate> 
    

    如果要在差异页面中绑定模板的值,可以使用TemplateBinding

      <ControlTemplate x:Key="GridTemplate">
    
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
    
                <ContentPresenter Grid.Row="0"  />
                <Label Grid.Row="1" BackgroundColor="Accent" Text="{TemplateBinding BindingContext.Name}" />
    
            </Grid>
        </ControlTemplate>
    

    有关代码示例的更多详细信息,您可以查看我之前完成的代码。 How to add a grid view under Master-Detail detail page in Xamarin Forms?

    解决方案 2:

    一个简单的方法是使用自定义控件作为模型。

    您可以查看以下链接中的示例。 https://stackoverflow.com/a/58928433/11850033

    【讨论】:

      猜你喜欢
      • 2021-12-27
      • 1970-01-01
      • 2020-02-21
      • 1970-01-01
      • 1970-01-01
      • 2021-05-01
      • 2015-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多